home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / dos / fs / files12.1 < prev    next >
Text File  |  1988-10-25  |  61KB  |  2,761 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i019:  files - file catalog utility V1.2
  5. Message-ID: <9824@swan.ulowell.edu>
  6. Date: 25 Oct 88 01:12:41 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2750
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 19
  13. Archive-name: dos/fs/files12.1
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    Makefile
  20. #    README
  21. #    TODO
  22. #    filereq.c
  23. #    files.c
  24. #    files.h
  25. #    gadget.c
  26. #    main.c
  27. #    memory.c
  28. #    menu.c
  29. #    newwildcmp.c
  30. #
  31. if `test ! -s Makefile`
  32. then
  33. echo "writing Makefile"
  34. cat > Makefile << '\Rogue\Monster\'
  35.  
  36. #   Makefile
  37. #
  38. #   -include:local must exist and my support library too
  39.  
  40. SYMS=    include:symbols.m
  41. SYMC=    include:local/makesymbols.c
  42. CFLAGS= +L +I$(SYMS)
  43. DEST=    srcc:files
  44.  
  45. SR1 = main.c
  46. SR2 = gadget.c
  47. SR3 = menu.c
  48. SR4 = files.c
  49. SR5 = memory.c
  50. SR6 = newwildcmp.c
  51. SR7 = filereq.c
  52.  
  53. OB1 = T:main.o
  54. OB2 = T:gadget.o
  55. OB3 = T:menu.o
  56. OB4 = T:files.o
  57. OB5 = T:memory.o
  58. OB6 = T:newwildcmp.o
  59. OB7 = T:filereq.o
  60.  
  61. SRCS= $(SR1) $(SR2) $(SR3) $(SR4) $(SR5) $(SR6) $(SR7)
  62. OBJS= $(OB1) $(OB2) $(OB3) $(OB4) $(OB5) $(OB6) $(OB7)
  63.  
  64. $(DEST): $(SYMS) $(OBJS)
  65.     ln +Q $(OBJS) -lsup32 -lc32 -o $(DEST)
  66.  
  67. $(OB1): $(SR1)
  68.     cc $(CFLAGS) $(SR1) -o $(OB1)
  69. $(OB2): $(SR2)
  70.     cc $(CFLAGS) $(SR2) -o $(OB2)
  71. $(OB3): $(SR3)
  72.     cc $(CFLAGS) $(SR3) -o $(OB3)
  73. $(OB4): $(SR4)
  74.     cc $(CFLAGS) $(SR4) -o $(OB4)
  75. $(OB5): $(SR5)
  76.     cc $(CFLAGS) $(SR5) -o $(OB5)
  77. $(OB6): $(SR6)
  78.     cc $(CFLAGS) $(SR6) -o $(OB6)
  79. $(OB7): $(SR7)
  80.     cc $(CFLAGS) $(SR7) -o $(OB7)
  81.  
  82. $(SYMS):    $(SYMC)
  83.     make -f include:local/Makefile
  84.  
  85. \Rogue\Monster\
  86. else
  87.   echo "will not over write Makefile"
  88. fi
  89. if [ `wc -c Makefile | awk '{printf $1}'` -ne 977 ]
  90. then
  91. echo `wc -c Makefile | awk '{print "Got " $1 ", Expected " 977}'`
  92. fi
  93. if `test ! -s README`
  94. then
  95. echo "writing README"
  96. cat > README << '\Rogue\Monster\'
  97.  
  98.  
  99. COMPILER NOTES:
  100.  
  101.     Be sure that you have working NewModifyProp() and AddGList() calls.
  102.     Aztec 3.4a screwed up the library call sequence for these.
  103.  
  104.     The source requires my support library SUP32.LIB to compile, as well
  105.     as a precompiled symbol table with all amiga includes (*/*.h), but not
  106.     high level includes (*.h ... stdio, etc...).
  107.  
  108.  
  109. \Rogue\Monster\
  110. else
  111.   echo "will not over write README"
  112. fi
  113. if [ `wc -c README | awk '{printf $1}'` -ne 354 ]
  114. then
  115. echo `wc -c README | awk '{print "Got " $1 ", Expected " 354}'`
  116. fi
  117. if `test ! -s TODO`
  118. then
  119. echo "writing TODO"
  120. cat > TODO << '\Rogue\Monster\'
  121.  
  122.     -string gadget is 'invisible'
  123.     -colon preceding the volume string gadget not lined up
  124.     -shift click several files to select them, slide-clicking
  125.  
  126. \Rogue\Monster\
  127. else
  128.   echo "will not over write TODO"
  129. fi
  130. if [ `wc -c TODO | awk '{printf $1}'` -ne 157 ]
  131. then
  132. echo `wc -c TODO | awk '{print "Got " $1 ", Expected " 157}'`
  133. fi
  134. if `test ! -s filereq.c`
  135. then
  136. echo "writing filereq.c"
  137. cat > filereq.c << '\Rogue\Monster\'
  138.  
  139. /*
  140.  *  STDFILE -- Standard File Requestor. Version 2.0a 15 June 1987
  141.  *
  142.  *  AUTHOR -- Peter da Silva      US (713) 497-4372
  143.  *
  144.  *  Reorganized by Matthew Dillon for use with * and ?.  Added:
  145.  *    -device name in File string gadget transfered to directory
  146.  *     gadget without closing the window.
  147.  *    -bug when requesting volume ""... current directory lock would
  148.  *     get unlocked!
  149.  *    -additional intuitive features added
  150.  *    -coding reorganized
  151.  *
  152.  *    Copyright (c) 1987 Peter da Silva, all rights reserved.
  153.  *    Changes (c)Copyright 1987 Matthew Dillon, all rights reserved.
  154.  *
  155.  *    This module may be freely used in any product, commercial or
  156.  *    otherwise, provided credit is given for this module and
  157.  *    and provided this notice remains intact in the source. The
  158.  *    intent of this module is to provide a standard file requestor
  159.  *    such as is available on the Macintosh, in GEM on the IBM-PC
  160.  *    and Atari ST, and in the Microsoft Windows software on the
  161.  *    IBM-PC. The advantage this module has over other requestors
  162.  *    is that it minimises disk accesses: an important consideration
  163.  *    given the structure of AmigaDos directories. If you need to
  164.  *    modify it for your needs, by all means go ahead... but please
  165.  *    conform to the intent of this program as stated above. If you
  166.  *    have suggestions for improvements, by all means call me at
  167.  *    the number listed above.
  168.  *
  169.  * Enhancements in the current version:
  170.  *
  171.  *    Gadgets now boxed. Display generally cleaned up.
  172.  *
  173.  *    True "dictionary order" for searches.
  174.  *
  175.  *    Default pattern can now be specified. Default file name now
  176.  *    specified in a single argument.
  177.  *
  178.  *    Directories always match.
  179.  *
  180.  *    Null pattern converted to "#?" universal wildcard.
  181.  *
  182.  *    If you attempt to build a file name longer than 128 characters the
  183.  *    screen will flash and the operation will be aborted.
  184.  *
  185.  *    "Volumes" gadget, using the device list code in "mounted". This
  186.  *    gadget brings up a list of all currently mounted volumes for
  187.  *    selection. Volumes leaves the directory specification intact, so
  188.  *    you can quickly return to where you left off.
  189.  *
  190.  *    With these enhancements it is now possible to select any file on
  191.  *    any device without touching the keyboard. This is now release 2.0,
  192.  *    as it is significantly better than 1.0.
  193.  *
  194.  * Acknowledgements:
  195.  *
  196.  *    Thanks to Jeff Lydiatt for the pattern matching code in PatMatch.c
  197.  *    Thanks to Jay Miner, =RJ= and the whole Amiga team for the Amiga
  198.  *    itself.
  199.  *
  200.  * Environment:
  201.  *
  202.  *    IntuitionBase and GfxBase must be open. dos.library must be open
  203.  *    under the name "DosLibrary". Link with PatMatch.o and VolList.o.
  204.  *
  205.  * Usage:
  206.  *
  207.  *    #define MAXFILENAME 128
  208.  *
  209.  *    int stdfile(title, default_file, default_pat, name);
  210.  *    char *title;
  211.  *    char *default_file;
  212.  *    char *default_pattern;
  213.  *    char name[MAXFILENAME];
  214.  *
  215.  *    +-----------------------------------+
  216.  *    |o| Title ------------------- |  |  | title parameter, or "File Name"
  217.  *    |-----------------------------------|
  218.  *    | Directory: [              ] | Directory parameter, or current.
  219.  *    | File name: [              ] | Default parameter, or empty.
  220.  *    | Pattern:   [              ] | Initially empty, if the user
  221.  *    | +-------------------------------+ | enters anything here it will
  222.  *    | | [Filename]               |  | | be used to select files. The
  223.  *    | | [Filename]               |  | | file display will also be empty
  224.  *    | | [Filename]               |@@| | to start with to avoid excess
  225.  *    | | [Filename]               |@@| | disk I/O. If the user selects
  226.  *    | |                   |@@| | here the directory will be
  227.  *    | |                   |@@| | scanned looking for files
  228.  *    | |                   |  | | matching the specified pattern,
  229.  *    | |                   |  | | or "*" if no pattern is given.
  230.  *    | |                   |  | |
  231.  *    | +-------------------------------+ | ACCEPT returns 1. CANCEL
  232.  *    | [ACCEPT]    [VOLUMES]    [CANCEL] | or the close gadget return 0.
  233.  *    +-----------------------------------+ VOLUMES displays volume names.
  234.  *
  235.  *    The number of filenames displayed is specified at compile time in the
  236.  *    constant MAXFILES. The maximum size of a filename is specified in the
  237.  *    constant MAXNAME. The parameter "Default file" will be broken into
  238.  *    directory and file parts.
  239.  */
  240.  
  241. char *Copyright =
  242. "stdfile V2.0a. Copyright (c) 1987 Peter da Silva. All rights reserved.";
  243.  
  244. #include <intuition/intuitionbase.h>
  245. #include <intuition/intuition.h>
  246. #include <libraries/dos.h>
  247. #include <libraries/dosextens.h>
  248. #include <exec/memory.h>
  249.  
  250. typedef unsigned char  ubyte;
  251. typedef unsigned short uword;
  252. typedef unsigned long  ulong;
  253. typedef struct FileInfoBlock FIB;
  254. typedef struct DeviceList    DEVLIST;
  255. typedef struct DosLibrary    DOSLIB;
  256. typedef struct DosInfo         DOSINFO;
  257. typedef struct RootNode      ROOTNODE;
  258. typedef struct IntuiMessage  IMESS;
  259.  
  260. extern void CalcPropGadget();
  261. extern void ProcessFileName();
  262.  
  263. extern void *malloc();
  264. extern void *GetMsg();
  265. extern struct Window *OpenWindow();
  266.  
  267. #define MAXFILES 8
  268. #define MAXNAME 32
  269. #define MAXFULL (MAXNAME*4)
  270.  
  271. /* SIZING PARAMS */
  272.  
  273. #define Z        NULL
  274. #define INDENT        6
  275. #define LEFTMAR     (INDENT-1)
  276. #define BORDER        3
  277. #define CHSIZ        8
  278. #define HT        CHSIZ
  279. #define BASELINE    6
  280.  
  281. /* GADGET BORDERS */
  282.  
  283. #define IN1        LEFTMAR+10*CHSIZ
  284. #define IN3        LEFTMAR+3
  285. #define IN4        -(INDENT+6*CHSIZ+1)
  286. #define IN5        -(INDENT+CHSIZ*2)
  287. #define IN6        ((WINWD-WD6)/2)
  288. #define WD1        -(INDENT+IN1)
  289. #define WD3        (6*CHSIZ)
  290. #define WD4        (6*CHSIZ)
  291. #define WD5        (CHSIZ*2+2)
  292. #define WD6        (7*CHSIZ)
  293. #define TP1        (CHSIZ+BORDER)
  294. #define TP2        (TP1+HT+1)
  295. #define TP3        (TP2+HT+1)
  296. #define TP4        -(BORDER+HT4-1)
  297. #define TP5        (TP3+HT+BORDER)
  298. #define HT4        (HT+1)
  299. #define HT5        CHSIZ*MAXFILES+INDENT
  300.  
  301. #define WINHT        (TP5 + HT5 + (-TP4) + BORDER)
  302. #define WINWD        (INDENT*4 + (MAXNAME+2)*CHSIZ)
  303. #define WININ        (640-WINWD)/2
  304. #define WINTP        (200-WINHT)/2
  305.  
  306. #define HOMEX        (INDENT+LEFTMAR)
  307. #define HOMEY        (TP5+BORDER)
  308. #define LASTX        (HOMEX+MAXNAME*CHSIZ)
  309. #define LASTY        (HOMEY+MAXFILES*CHSIZ)
  310.  
  311. #define BTP        TP5
  312. #define BIN        LEFTMAR
  313. #define BWD        (WINWD-INDENT-BIN)
  314. #define BHT        (WINHT-BTP-(-TP4+BORDER+1))
  315.  
  316. #define SF        GADGHCOMP|GRELWIDTH
  317. #define SEL        SELECTED
  318. #define BF1        GADGHCOMP|GRELBOTTOM
  319. #define BF2        GADGHCOMP|GRELBOTTOM|GRELRIGHT
  320. #define PF        GRELRIGHT
  321.  
  322. #define SA        RELVERIFY
  323. #define CEN        STRINGCENTER
  324. #define BA        RELVERIFY
  325. #define PA        RELVERIFY
  326.  
  327. #define SI(n)      (APTR)&STD_String[n]
  328. #define G(n)       &STD_Gadget[n]
  329. #define IMAG       (APTR)&STD_Image
  330. #define PROP       (APTR)&STD_Prop
  331.  
  332. #define SG       STRGADGET
  333. #define BG       BOOLGADGET
  334. #define PG       PROPGADGET
  335.  
  336. #define FP       AUTOBACKPEN
  337. #define BP       AUTOFRONTPEN
  338.  
  339. #define OKTEXT       &STD_OK
  340. #define NOTEXT       &STD_CANCEL
  341. #define VLTEXT       &STD_VOLUME
  342.  
  343. static int DoneFlag;
  344.  
  345. #define DirName    SBuffer[0]
  346. #define FileName   SBuffer[1]
  347. #define PatName    SBuffer[2]
  348. #define STRINGS    3
  349.  
  350. static UBYTE SBuffer[STRINGS][MAXFULL];
  351. static UBYTE Undo[MAXFULL];
  352.  
  353. static struct StringInfo STD_String[STRINGS] = {
  354.     {SBuffer[0],Undo,0,MAXFULL,0},
  355.     {SBuffer[1],Undo,0,MAXFULL,0},
  356.     {SBuffer[2],Undo,0,MAXFULL,0}
  357. };
  358.  
  359. static struct PropInfo STD_Prop = { AUTOKNOB|FREEVERT, 0, 0, 0, 0 };
  360.  
  361. static struct IntuiText STD_OK =
  362.     { FP, BP, JAM2, 0, 1, Z, (UBYTE *)"ACCEPT", Z };
  363. static struct IntuiText STD_CANCEL =
  364.     { FP, BP, JAM2, 0, 1, Z, (UBYTE *)"CANCEL", Z };
  365. static struct IntuiText STD_VOLUME =
  366.     { FP, BP, JAM2, 0, 1, Z, (UBYTE *)"VOLUMES", Z };
  367.  
  368. #define BUTTONS 3
  369. #define BUTVEC 8
  370.  
  371. static SHORT butvecs[BUTTONS][BUTVEC*2] = {
  372.     { -2, HT4, -2, -1, WD3+1,-1, WD3+1,HT4, -3, HT4, -3,-1, WD3+2,-1, WD3+2, HT4 },
  373.     { -2, HT4, -2, -1, WD4+1,-1, WD4+1,HT4, -3, HT4, -3,-1, WD4+2,-1, WD4+2, HT4 },
  374.     { -2, HT4, -2, -1, WD6+1,-1, WD6+1,HT4, -3, HT4, -3,-1, WD6+2,-1, WD6+2, HT4 }
  375. };
  376.  
  377. static struct Border ButBorder[BUTTONS] = {
  378.     {0, 0, FP, BP, JAM1, BUTVEC, butvecs[0], NULL},
  379.     {0, 0, FP, BP, JAM1, BUTVEC, butvecs[1], NULL},
  380.     {0, 0, FP, BP, JAM1, BUTVEC, butvecs[2], NULL}
  381. };
  382.  
  383. #define BB(n) (APTR)&ButBorder[n]
  384.  
  385. static struct Image STD_Image;
  386.  
  387. #define DIRID 0
  388. #define FILID 1
  389. #define PATID 2
  390. #define YESID 3
  391. #define CANID 4
  392. #define VOLID 5
  393. #define BARID 6
  394. #define GADGETS 7
  395.  
  396. static struct Gadget STD_Gadget[GADGETS] = {
  397.     /*NEXT, LFT, TP,WDTH, H, FLAG,  ACT, TYP, REND, Z, TXT, Z, SPEC, ID, Z */
  398.     { G(1), IN1,TP1, WD1,HT, SF,     SA,  SG,    Z, Z,   Z, Z, SI(0), 0, 0 },
  399.     { G(2), IN1,TP2, WD1,HT, SF|SEL, SA,  SG,    Z, Z,   Z, Z, SI(1), 1, 0 },
  400.     { G(3), IN1,TP3, WD1,HT, SF,     SA,  SG,    Z, Z,   Z, Z, SI(2), 2, 0 },
  401.     { G(4), IN3,TP4, WD3,HT4,BF1,    BA,  BG,BB(0), Z, OKTEXT, Z,  Z, 3, 0 },
  402.     { G(5), IN4,TP4, WD4,HT4,BF2,    BA,  BG,BB(1), Z, NOTEXT, Z,  Z, 4, 0 },
  403.     { G(6), IN6,TP4, WD6,HT4,BF1,    BA,  BG,BB(2), Z, VLTEXT, Z,  Z, 5, 0 },
  404.     { NULL, IN5,TP5, WD5,HT5,PF,     PA,  PG, IMAG, Z,     Z, Z,    PROP, 6, 0 }
  405. };
  406.  
  407. static struct NewWindow STD_NewWindow = {
  408.     WININ, WINTP, WINWD, WINHT, -1, -1,
  409.     REFRESHWINDOW|MOUSEBUTTONS|GADGETUP|CLOSEWINDOW,
  410.     WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SIMPLE_REFRESH|ACTIVATE,
  411.     G(0), NULL, (ubyte *)"File Name Requestor",
  412.     NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN
  413. };
  414.  
  415. static struct Window *STD_Window;
  416.  
  417. #define NVEC 6
  418.  
  419. static SHORT Vectors[NVEC*2] = {
  420.     BIN+1, BTP,
  421.     BIN+1, BTP+BHT,
  422.     BIN+BWD, BTP+BHT,
  423.     BIN+BWD, BTP,
  424.     BIN, BTP,
  425.     BIN, BTP+BHT
  426. };
  427.  
  428. static struct Border STD_FileBox = {
  429.     0, 0, FP, BP, JAM1, NVEC, Vectors, NULL
  430. };
  431.  
  432. static struct IntuiText STD_Text[3] = {
  433.     { FP, BP, JAM2, 0, 0, NULL, (UBYTE *)"Directory:", NULL },
  434.     { FP, BP, JAM2, 0, 0, NULL, (UBYTE *)"File Name:", NULL },
  435.     { FP, BP, JAM2, 0, 0, NULL, (UBYTE *)"Pattern:", NULL }
  436. };
  437.  
  438. static
  439. OpenFileWindow()
  440. {
  441.     extern struct IntuitionBase *IntuitionBase;
  442.     int i;
  443.  
  444.     /* Rebuild gadget list */
  445.  
  446.     STD_NewWindow.FirstGadget = &STD_Gadget[0];
  447.     for(i = 0; i < GADGETS; i++)
  448.     STD_Gadget[i].NextGadget = (i==GADGETS-1)?(0):(&STD_Gadget[i+1]);
  449.     for(i = 0; i < STRINGS; i++) {
  450.     STD_String[i].BufferPos = strlen(SBuffer[i]);
  451.     STD_String[i].DispPos = 0;
  452.     }
  453.     STD_Prop.VertBody = 0xFFFF;
  454.     STD_Prop.VertPot = 0;
  455.  
  456.     if (!(STD_Window = OpenWindow(&STD_NewWindow)))
  457.     return(0);
  458.  
  459.     /* This optional line will activate a string gadget     */
  460.     if (IntuitionBase->LibNode.lib_Version > 32)
  461.     ActivateGadget(G(1),STD_Window,0L);
  462.     CalcPropGadget();
  463.     PaintFileWindow();
  464.     return (1);
  465. }
  466.  
  467. static
  468. CloseFileWindow()
  469. {
  470.     STD_NewWindow.LeftEdge = STD_Window->LeftEdge;
  471.     STD_NewWindow.TopEdge = STD_Window->TopEdge;
  472.     if (STD_Window)
  473.     CloseWindow(STD_Window);
  474. }
  475.  
  476. static int State;
  477.  
  478. #define INITIAL 0
  479. #define DIRECTORY 1
  480.  
  481. static
  482. PaintFileWindow()
  483. {
  484.     DrawBorder(STD_Window->RPort, &STD_FileBox, 0, 0);
  485.     PrintIText(STD_Window->RPort, &STD_Text[0], LEFTMAR, TP1);
  486.     PrintIText(STD_Window->RPort, &STD_Text[1], LEFTMAR, TP2);
  487.     PrintIText(STD_Window->RPort, &STD_Text[2], LEFTMAR, TP3);
  488.     if (State == DIRECTORY)
  489.     PrintFileNames();
  490. }
  491.  
  492. static int FirstFile;
  493. static int Selected;
  494. static int NumFiles;
  495.  
  496. static struct dirent {
  497.     struct dirent *nextfile;
  498.     SHORT filetype;
  499.     char *filename;
  500. } *NameList, **NameTable;
  501.  
  502. #define FILETYPE 0
  503. #define DIRTYPE 1
  504. #define VOLTYPE 2
  505.  
  506. static
  507. PrintFileNames()
  508. {
  509.     int i;
  510.  
  511.     for (i = 0; i < MAXFILES; ++i) {
  512.     SetBPen(STD_Window->RPort, BP);
  513.     SetAPen(STD_Window->RPort, BP);
  514.     RectFill(STD_Window->RPort, HOMEX, HOMEY+i*CHSIZ, LASTX, HOMEY+(i+1)*CHSIZ);
  515.     if (i+FirstFile < NumFiles)
  516.         PrintName(i+FirstFile, i+FirstFile == Selected);
  517.     }
  518. }
  519.  
  520. static
  521. PrintName(file, hilite)
  522. int file;
  523. int hilite;
  524. {
  525.     int i;
  526.  
  527.     i = file - FirstFile;
  528.  
  529.     Move(STD_Window->RPort, HOMEX, HOMEY+i*CHSIZ+BASELINE);
  530.     if (hilite == 0) {
  531.     SetBPen(STD_Window->RPort, BP);
  532.     if(NameTable[file]->filetype == FILETYPE)
  533.         SetAPen(STD_Window->RPort, FP);
  534.     else
  535.         SetAPen(STD_Window->RPort, 3);
  536.     } else {
  537.     SetAPen(STD_Window->RPort, BP);
  538.     if(NameTable[file]->filetype == FILETYPE)
  539.         SetBPen(STD_Window->RPort, FP);
  540.     else
  541.         SetBPen(STD_Window->RPort, 3);
  542.     }
  543.     Text(STD_Window->RPort, NameTable[file]->filename, strlen(NameTable[file]->filename));
  544. }
  545.  
  546. static
  547. void
  548. CalcPropGadget()
  549. {
  550.     int VertPot, VertBody;
  551.  
  552.     if (State == INITIAL)
  553.     return;
  554.     if (NumFiles <= MAXFILES) {
  555.     VertBody = 0xFFFF;
  556.     VertPot = 0;
  557.     FirstFile = 0;
  558.     } else {
  559.     VertBody = ((MAXFILES<<16)-1) / NumFiles;
  560.     VertPot = 0;
  561.     FirstFile = 0;
  562.     }
  563.     ModifyProp(&STD_Gadget[BARID], STD_Window, NULL,
  564.     STD_Prop.Flags, 0, VertPot, 0, VertBody
  565.     );
  566. }
  567.  
  568. static
  569. void
  570. CalcFilePosition()
  571. {
  572.     short old_pos;
  573.  
  574.     if (State == INITIAL)
  575.      return;
  576.     old_pos = FirstFile;
  577.     if (NumFiles<=MAXFILES) {
  578.     FirstFile = 0;
  579.     } else {
  580.     int VertPot = STD_Prop.VertPot;
  581.     FirstFile = ((VertPot+1)*(NumFiles-MAXFILES))>>16;
  582.     }
  583.     if (old_pos != FirstFile)
  584.     PrintFileNames();
  585. }
  586.  
  587. FreeList(list)
  588. struct dirent *list;
  589. {
  590.     struct dirent *ptr;
  591.  
  592.     while(list) {
  593.     ptr = list->nextfile;
  594.     if (list->filename)
  595.         free(list->filename);
  596.     free(list);
  597.     list = ptr;
  598.     }
  599. }
  600.  
  601. static
  602. ReadNewDir()
  603. {
  604.     struct dirent *NewList, **NewTable, *ptr;
  605.     int NewCount;
  606.     FIB *fib;
  607.     BPTR dirlock;
  608.  
  609.     if (State != DIRECTORY) {
  610.     NameTable = 0;
  611.     NameList = 0;
  612.     }
  613.     if (DirName[0]) {
  614.         dirlock = Lock(DirName, ACCESS_READ);
  615.     } else {
  616.     BPTR ram;
  617.     if (ram = Lock("RAM:", ACCESS_READ)) {
  618.         dirlock = CurrentDir(ram);
  619.         CurrentDir(dirlock);
  620.         dirlock = DupLock(dirlock); /*  added */
  621.         UnLock(ram);
  622.     }
  623.     }
  624.     if (!dirlock)
  625.     return(0);
  626.     if ((fib = (FIB *)malloc(sizeof(FIB))) == NULL) {
  627.     UnLock(dirlock);
  628.     return 0;
  629.     }
  630.     if (!Examine(dirlock, fib)) {
  631.     UnLock(dirlock);
  632.     free(fib);
  633.     return 0;
  634.     }
  635.     if (fib->fib_DirEntryType < 0) {
  636.     UnLock(dirlock);
  637.     free(fib);
  638.     return 0;
  639.     }
  640.     NewList = 0;
  641.     NewCount = 0;
  642.     while(ExNext(dirlock, fib)) {
  643.     NewCount += 1;
  644.     ptr = (struct dirent *)malloc(sizeof(struct dirent));
  645.     if (ptr == 0) {
  646.         FreeList(NewList);
  647.         UnLock(dirlock);
  648.         free(fib);
  649.         return(0);
  650.     }
  651.     ptr->nextfile = NewList;
  652.     ptr->filetype = (fib->fib_DirEntryType<0)?FILETYPE:DIRTYPE;
  653.     ptr->filename = malloc(strlen(fib->fib_FileName)+1);
  654.     if (ptr->filename == 0) {
  655.         FreeList(ptr);
  656.         UnLock(dirlock);
  657.         free(fib);
  658.         return(0);
  659.     }
  660.     strcpy(ptr->filename, fib->fib_FileName);
  661.     NewList = ptr;
  662.     }
  663.     free(fib);
  664.     if (DirName[0])
  665.     UnLock(dirlock);
  666.     NewTable = malloc(sizeof(struct dirent *) * NewCount);
  667.     if (NewTable==0) {
  668.     FreeList(NewList);
  669.     return(0);
  670.     }
  671.     FreeList(NameList);
  672.     NameList = NewList;
  673.     if (NameTable)
  674.     free(NameTable);
  675.     NameTable = NewTable;
  676.     if (PatName[0]==0)
  677.     SetPatName("*");
  678.     State = DIRECTORY;
  679.     Selected = -1;
  680.     ReCalcPattern();
  681. }
  682.  
  683.  
  684. static
  685. ReadVol()
  686. {
  687.     struct dirent *NewList, **NewTable, *ptr;
  688.     int NewCount;
  689.     char name[MAXNAME];
  690.  
  691.     if (State != DIRECTORY) {
  692.     NameTable = 0;
  693.     NameList = 0;
  694.     }
  695.     OpenVolList();
  696.     NewList = 0;
  697.     NewCount = 0;
  698.     while(ReadVolList(name)) {
  699.     if (strcmp(name, "RAM Disk:") == 0)
  700.         strcpy(name, "ram:");
  701.     NewCount += 1;
  702.     ptr = (struct dirent *)malloc(sizeof(struct dirent));
  703.     if (ptr==0) {
  704.         FreeList(NewList);
  705.         return(0);
  706.     }
  707.     ptr->nextfile = NewList;
  708.     ptr->filetype = VOLTYPE;
  709.     ptr->filename = malloc(strlen(name)+1);
  710.     if (ptr->filename == 0) {
  711.         FreeList(ptr);
  712.         return(0);
  713.     }
  714.     strcpy(ptr->filename, name);
  715.     NewList = ptr;
  716.     }
  717.     CloseVolList();
  718.     NewTable = malloc(sizeof(struct dirent *)*NewCount);
  719.     if (NewTable==0) {
  720.     FreeList(NewList);
  721.     return(0);
  722.     }
  723.     FreeList(NameList);
  724.     NameList = NewList;
  725.     if (NameTable)
  726.     free(NameTable);
  727.     NameTable = NewTable;
  728.  
  729.     if (PatName[0]==0)
  730.     SetPatName("*");
  731.  
  732.     State = DIRECTORY;
  733.     Selected = -1;
  734.  
  735.     ReCalcPattern();
  736. }
  737.  
  738. /* this routine does a true dictionary search:
  739.  *
  740.  *        Devs < devs but Devs > devices
  741.  */
  742.  
  743. static
  744. table_compare(p1, p2)
  745. struct dirent **p1, **p2;
  746. {
  747.     char *s1, *s2;
  748.     char c1, c2;
  749.     char firstdiff;
  750.  
  751.     s1 = (*p1)->filename;
  752.     s2 = (*p2)->filename;
  753.     firstdiff = 0;
  754.  
  755.     while(*s1 && *s2) {
  756.     c1 = *s1++;
  757.     c2 = *s2++;
  758.     if (firstdiff==0)
  759.         firstdiff = c1 - c2;
  760.     if (c1 >= 'A' && c1 <= 'Z') c1 = c1+'@';
  761.     if (c2 >= 'A' && c2 <= 'Z') c2 = c2+'@';
  762.     if (c1 != c2)
  763.         return c1 - c2;
  764.     }
  765.     return firstdiff;
  766. }
  767.  
  768. static
  769. sort_table()
  770. {
  771.     qsort(NameTable, NumFiles, sizeof(struct dirent *), table_compare);
  772.     return 1;
  773. }
  774.  
  775. static
  776. ReCalcPattern()
  777. {
  778.     if (State != DIRECTORY) {
  779.     ReadNewDir();
  780.     } else {
  781.     struct dirent *ptr;
  782.  
  783.     if (!PatName[0])
  784.         SetPatName("*");
  785.     NumFiles = 0;
  786.     for (ptr = NameList; ptr; ptr=ptr->nextfile) {
  787.         /* Directories always match. Is this good? */
  788.         if (ptr->filetype == DIRTYPE || ptr->filetype == VOLTYPE || newwildcmp(PatName, ptr->filename)) {
  789.         NameTable[NumFiles] = ptr;
  790.         NumFiles++;
  791.         }
  792.     }
  793.     sort_table();
  794.     CalcPropGadget();
  795.     Selected = -1;
  796.     PrintFileNames();
  797.     }
  798. }
  799.  
  800. static
  801. SetGadgetText(id, text)
  802. int id;
  803. char *text;
  804. {
  805.     int position;
  806.  
  807.     position = RemoveGadget(STD_Window, G(id));
  808.     if (position != -1) {
  809.     strcpy(SBuffer[id], text);
  810.     STD_String[id].BufferPos = strlen(text);
  811.     position = AddGadget(STD_Window, G(id), -1);
  812.     if (position != -1)
  813.         RefreshGadgets(G(id), STD_Window, NULL);
  814.     }
  815. }
  816.  
  817.  
  818. static
  819. SetDirName(name)
  820. char *name;
  821. {
  822.     char buffer[MAXFULL+1], *ptr;
  823.     int  index;
  824.     char lastchar;
  825.  
  826.     /* Can't enter a file name too long. */
  827.  
  828.     if (strlen(DirName) + strlen(name) + 1 > MAXFULL) {
  829.     DisplayBeep();
  830.     return(0);
  831.     }
  832.     index = 0;
  833.     lastchar = 0;
  834.     for (ptr = (char *)DirName; *ptr; ptr++)
  835.     buffer[index++] = lastchar = *ptr;
  836.     if (lastchar != ':' && lastchar != 0)
  837.     buffer[index++] = '/';
  838.     strcpy(&buffer[index], name);
  839.     SetGadgetText(DIRID, buffer);
  840.     SetGadgetText(FILID, "");
  841.     return(1);
  842. }
  843.  
  844. static
  845. SetFileName(name)
  846. char *name;
  847. {
  848.     /* Can't enter a file name too long. */
  849.     if (strlen(DirName) + strlen(name) + 1 > MAXFULL) {
  850.     DisplayBeep();
  851.     return(0);
  852.     }
  853.     SetGadgetText(FILID, name);
  854.     return(1);
  855. }
  856.  
  857. static
  858. SetPatName(name)
  859. char *name;
  860. {
  861.     SetGadgetText(PATID, name);
  862. }
  863.  
  864. static
  865. ProcessGadget(id)
  866. int id;
  867. {
  868.     switch(id) {
  869.     case DIRID: ReadNewDir();       break;
  870.     case FILID: ProcessFileName();  break;
  871.     case PATID: ReCalcPattern();    break;
  872.     case BARID: CalcFilePosition(); break;
  873.     case YESID: DoneFlag = 1;        break;
  874.     case CANID: DoneFlag = -1;        break;
  875.     case VOLID: ReadVol();          break;
  876.     }
  877. }
  878.  
  879. /*
  880.  *  ProcessFileName() added by Matthew Dillon.  If the requested file is
  881.  *  actually a directory, do a ReadNewDir() instead of quiting.
  882.  */
  883.  
  884. void
  885. ProcessFileName()
  886. {
  887.     register char *ptr;
  888.     register short len;
  889.     BPTR fillock;
  890.     char buf[128];
  891.     FIB *fib = (FIB *)malloc(sizeof(FIB));
  892.  
  893.     if (fib == NULL) {
  894.     DoneFlag = 1;
  895.     return;
  896.     }
  897.     for (ptr = (char *)FileName; *ptr; ++ptr) {
  898.     if (*ptr == ':') {
  899.         DirName[0] = '\0';
  900.         break;
  901.     }
  902.     }
  903.     strcpy(buf, DirName);
  904.     if (FileName[0]) {
  905.     if (len = strlen(buf)) {
  906.         if (buf[len-1]!=':')
  907.         strcat(buf, "/");
  908.     }
  909.     strcat(buf, FileName);
  910.     if (fillock = Lock(buf, ACCESS_READ)) {
  911.         if (Examine(fillock, fib)) {
  912.         if (fib->fib_DirEntryType > 0) {
  913.             SetGadgetText(DIRID, buf);
  914.             SetGadgetText(FILID, "");
  915.             ReadNewDir();
  916.             free(fib);
  917.             UnLock(fillock);
  918.             return;
  919.         }
  920.         }
  921.         UnLock(fillock);
  922.     }
  923.     }
  924.     free(fib);
  925.     DoneFlag = 1;
  926. }
  927.  
  928.  
  929. static
  930. ProcessMouse(x, y, code, seconds, micros)
  931. {
  932.     int NewSelected;
  933.     static int oseconds = 0, omicros = 0;
  934.  
  935.     if (x < HOMEX || y < HOMEY || x >= LASTX || y >= LASTY)
  936.     return;
  937.     if ((code & SELECTUP) == SELECTUP)
  938.     return;
  939.     if (State != DIRECTORY) {
  940.     ReadNewDir();
  941.     return;
  942.     }
  943.     NewSelected = (y-HOMEY)/CHSIZ + FirstFile;
  944.     if (NewSelected == Selected) {
  945.     if (Selected != -1) {
  946.         if (DoubleClick(oseconds, omicros, seconds, micros)) {
  947.         if (NameTable[Selected]->filetype == DIRTYPE) {
  948.             if (SetDirName(NameTable[Selected]->filename))
  949.             ReadNewDir();
  950.         } else if (NameTable[Selected]->filetype == VOLTYPE) {
  951.             SetGadgetText(DIRID, NameTable[Selected]->filename);
  952.             SetGadgetText(FILID, "");
  953.             ReadNewDir();
  954.         } else if (!SetFileName(NameTable[Selected]->filename)) {
  955.             Selected = -1;
  956.             DoneFlag = 1;
  957.         }
  958.         }
  959.     }
  960.     } else {
  961.     if (Selected != -1 && Selected >= FirstFile && Selected < FirstFile+MAXFILES)
  962.         PrintName(Selected, 0);
  963.     Selected = NewSelected;
  964.     if (Selected >= NumFiles) {
  965.         Selected = -1;
  966.     } else {
  967.         if (SetFileName(NameTable[Selected]->filename))
  968.         PrintName(Selected, 1);
  969.         else
  970.         Selected = -1;
  971.         if (IntuitionBase->LibNode.lib_Version > 32)
  972.         ActivateGadget(G(1),STD_Window,0L);
  973.     }
  974.     }
  975.     oseconds = seconds;
  976.     omicros = micros;
  977. }
  978.  
  979. stdfile(title, deffile, defpat, name)
  980. char *title, *deffile, *defpat, *name;
  981. {
  982.     IMESS *im;
  983.  
  984.     if(title)
  985.     STD_NewWindow.Title = (UBYTE *)title;
  986.     else
  987.     STD_NewWindow.Title = (UBYTE *)"Enter File Name";
  988.     if (deffile) {
  989.     int i;
  990.     for (i = strlen(deffile)-1; i >= 0; --i) {
  991.         if (deffile[i]==':' || deffile[i]=='/') {
  992.         int hold;
  993.         strcpy(FileName, &deffile[i+1]);
  994.         if (deffile[i]==':')
  995.             i++;
  996.         hold = deffile[i];
  997.         deffile[i] = 0;
  998.         strcpy(DirName, deffile);
  999.         deffile[i] = hold;
  1000.         break;
  1001.         }
  1002.     }
  1003.     if (i < 0) {
  1004.         strcpy(FileName, deffile);
  1005.         DirName[0] = 0;
  1006.     }
  1007.     } else {
  1008.     DirName[0] = 0;
  1009.     FileName[0] = 0;
  1010.     }
  1011.     if (defpat)
  1012.     strcpy(PatName, defpat);
  1013.     else
  1014.     PatName[0] = 0;
  1015.  
  1016.     State = INITIAL;
  1017.     NameTable = 0;
  1018.     NameList = 0;
  1019.  
  1020.     if(!OpenFileWindow())
  1021.     return(0);
  1022.     DoneFlag = 0;
  1023.     while (!DoneFlag) {
  1024.     Wait(1<<STD_Window->UserPort->mp_SigBit);
  1025.     while(im = GetMsg(STD_Window->UserPort)) {
  1026.         switch(im->Class) {
  1027.         case CLOSEWINDOW:
  1028.         DoneFlag = -1;
  1029.         break;
  1030.         case MOUSEBUTTONS:
  1031.         ProcessMouse(im->MouseX, im->MouseY, im->Code, im->Seconds, im->Micros);
  1032.         break;
  1033.         case GADGETUP:
  1034.         ProcessGadget(((struct Gadget *)im->IAddress)->GadgetID);
  1035.         break;
  1036.         case REFRESHWINDOW:
  1037.         BeginRefresh(STD_Window);
  1038.         PaintFileWindow();
  1039.         EndRefresh(STD_Window, 1);
  1040.         break;
  1041.         }
  1042.         ReplyMsg(im);
  1043.     }
  1044.     }
  1045.     CloseFileWindow();
  1046.     FreeList(NameList);
  1047.  
  1048.     if (NameTable)
  1049.     free(NameTable);
  1050.     if (DoneFlag == 1) {
  1051.     int len;
  1052.  
  1053.     strcpy(name, DirName);
  1054.     if (FileName[0]) {
  1055.         if (len = strlen(name)) {
  1056.         if (name[len-1]!=':')
  1057.             strcat(name, "/");
  1058.         }
  1059.         strcat(name, FileName);
  1060.         return(1);
  1061.     }
  1062.     }
  1063.     return(0);
  1064. }
  1065.  
  1066. /*
  1067.  *  VOLLIST.C
  1068.  */
  1069.  
  1070. #define toAPTR(b) ((b)<<2)
  1071. #define toBPTR(a) ((a)>>2)
  1072.  
  1073. struct DeviceList *list;
  1074.  
  1075. OpenVolList()
  1076. {
  1077.     extern DOSLIB *DOSBase;
  1078.     ROOTNODE *root;
  1079.     DOSINFO  *info;
  1080.  
  1081.     root =   (ROOTNODE *)DOSBase->dl_Root;
  1082.     info =   (DOSINFO  *)toAPTR(root->rn_Info);
  1083.     list = (DEVLIST *)toAPTR(info->di_DevInfo);
  1084. }
  1085.  
  1086. ReadVolList(name)
  1087. char *name;
  1088. {
  1089.     register DEVLIST *next;
  1090.  
  1091.     while(list) {
  1092.     next = (DEVLIST *)toAPTR(list->dl_Next);
  1093.     if (list->dl_Type == DLT_VOLUME) {
  1094.         char *ptr;
  1095.         int count;
  1096.         ptr = (char *)toAPTR((BPTR)list->dl_Name);
  1097.         count = *ptr++;
  1098.         if (count > 30)
  1099.         count = 30;
  1100.         strncpy(name, ptr, count);
  1101.         name[count++] = ':';
  1102.         name[count] = 0;
  1103.         list = next;
  1104.         return(1);
  1105.     }
  1106.     list = next;
  1107.     }
  1108.     return(0);
  1109. }
  1110.  
  1111. CloseVolList()
  1112. {
  1113. }
  1114.  
  1115.  
  1116. \Rogue\Monster\
  1117. else
  1118.   echo "will not over write filereq.c"
  1119. fi
  1120. if [ `wc -c filereq.c | awk '{printf $1}'` -ne 22956 ]
  1121. then
  1122. echo `wc -c filereq.c | awk '{print "Got " $1 ", Expected " 22956}'`
  1123. fi
  1124. if `test ! -s files.c`
  1125. then
  1126. echo "writing files.c"
  1127. cat > files.c << '\Rogue\Monster\'
  1128.  
  1129. /*
  1130.  *  FILES.C
  1131.  *
  1132.  *  File Manager!
  1133.  *
  1134.  *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
  1135.  */
  1136.  
  1137. #include "files.h"
  1138.  
  1139. extern LOCK *Lock();
  1140. extern LOCK *ParentDir(), *CurrentDir();
  1141. extern void *malloc();
  1142. extern void addentry();
  1143.  
  1144. RECORD *Rbase;        /*  All entries          */
  1145. RECORD *DisplayTop;    /*  Entry at the display top */
  1146. RECORD *Highlighted;    /*  Highlighted entry         */
  1147. short  MaxNameLen;
  1148. long   NumEntries;
  1149. long   NumSelected;
  1150. long   NumTop;
  1151. long   NewNumTop;
  1152. FIB    *Fib;
  1153. short  Modified;
  1154.  
  1155. short  Xs, Xe, Ys, Ye, Rows, Cols;
  1156.  
  1157. char Title[80];
  1158.  
  1159. redisplay(newtop)
  1160. {
  1161.     short i;
  1162.     short noscroll = 0;
  1163.     uword percent, fill;
  1164.     RECORD *rec;
  1165.  
  1166.     bigboxbounds(&Xs,&Xe,&Ys,&Ye);
  1167.     Rows = (Ye-Ys)/Rp->TxHeight;
  1168.     Cols = (Xe-Xs)/Rp->TxWidth;
  1169.  
  1170.     if (newtop) {
  1171.     long delta = NumTop - NewNumTop;
  1172.     if (delta < 0)
  1173.         delta = -delta;
  1174.     if (delta >= Rows)
  1175.         noscroll = 1;
  1176.     }
  1177.     while (DisplayTop && !(DisplayTop->flags & R_SELECTED))
  1178.     DisplayTop = DisplayTop->next;
  1179.     if (newtop) {
  1180.     while (NewNumTop != NumTop && DisplayTop) {
  1181.         if (NewNumTop < NumTop) {
  1182.         do {
  1183.             DisplayTop = DisplayTop->prev;
  1184.         } while (DisplayTop && !(DisplayTop->flags & R_SELECTED));
  1185.         --NumTop;
  1186.         if (DisplayTop && !noscroll) {
  1187.             ScrollRaster(Rp, 0, -Rp->TxHeight, Xs, Ys, Xe-1, Ye-1);
  1188.             displayat(DisplayTop, 0);
  1189.         }
  1190.         } else {
  1191.         do {
  1192.             DisplayTop = DisplayTop->next;
  1193.         } while (DisplayTop && !(DisplayTop->flags & R_SELECTED));
  1194.         ++NumTop;
  1195.         if (DisplayTop && !noscroll) {
  1196.             ScrollRaster(Rp, 0, Rp->TxHeight, Xs, Ys, Xe-1, Ye-1);
  1197.             displayrow(Rows-1);
  1198.         }
  1199.         }
  1200.     }
  1201.     if (DisplayTop && !noscroll)
  1202.         return(0);
  1203.     }
  1204.     sprintf(Title, "%ld/%ld", NumSelected, NumEntries);
  1205.     title(Title);
  1206.     if (DisplayTop == NULL) {
  1207.     DisplayTop = Rbase;
  1208.     NumTop = 0;
  1209.     }
  1210.     if (!newtop) {
  1211.     percent = fill = 0xFFFF;
  1212.     if (NumSelected) {
  1213.         if (NumTop+(Rows>>1) > NumSelected)
  1214.         percent = 0xFFFF;
  1215.         else
  1216.         percent = (NumTop + (Rows>>1)) * 0xFFFF / NumSelected;
  1217.         fill = Rows * 0xFFFF / NumSelected;
  1218.         if (Rows > NumSelected)
  1219.         fill = 0xFFFF;
  1220.     }
  1221.     setslider(percent, fill);
  1222.     }
  1223.     SetAPen(Rp, 0);
  1224.     RectFill(Rp, Xs, Ys, Xe-1, Ye-1);
  1225.     SetAPen(Rp, 1);
  1226.     for (rec = DisplayTop, i = 0; rec && i < Rows; rec = rec->next) {
  1227.     if (!(rec->flags & R_SELECTED))
  1228.         continue;
  1229.     displayat(rec, i);
  1230.     ++i;
  1231.     }
  1232. }
  1233.  
  1234. redisplayone(rec)
  1235. RECORD *rec;
  1236. {
  1237.     RECORD *nrec;
  1238.     short i;
  1239.  
  1240.     for (i = 0, nrec = DisplayTop; nrec && i < Rows; nrec = nrec->next) {
  1241.     if (!(nrec->flags & R_SELECTED))
  1242.         continue;
  1243.     if (nrec == rec)
  1244.         break;
  1245.     ++i;
  1246.     }
  1247.     if (i < Rows && nrec == rec) {
  1248.     SetAPen(Rp, 0);
  1249.     RectFill(Rp, Xs, Ys + (Rp->TxHeight*i), Xe-1, Ys + (Rp->TxHeight*i) + Rp->TxHeight - 1);
  1250.     SetAPen(Rp, 1);
  1251.     displayat(rec, i);
  1252.     }
  1253. }
  1254.  
  1255. displayrow(row)
  1256. {
  1257.     register RECORD *rec = DisplayTop;
  1258.     register short i = row;
  1259.  
  1260.     while (i && rec) {
  1261.     rec = rec->next;
  1262.     while (rec && !(rec->flags & R_SELECTED))
  1263.         rec = rec->next;
  1264.     --i;
  1265.     }
  1266.     if (rec && row < Rows)
  1267.     displayat(rec, row);
  1268. }
  1269.  
  1270. displayat(rec, i)
  1271. RECORD *rec;
  1272. {
  1273.     short len;
  1274.  
  1275.     len = strlen(rec->name);
  1276.     if (len > Cols)
  1277.     len = Cols;
  1278.     if (rec == Highlighted) {
  1279.     SetAPen(Rp, 0);
  1280.     SetBPen(Rp, 1);
  1281.     }
  1282.     Move(Rp, Xs, Ys + (Rp->TxHeight*i) + Rp->TxBaseline);
  1283.     Text(Rp, rec->name, len);
  1284.     if (Cols > MaxNameLen && rec->comment) {
  1285.     len = strlen(rec->comment);
  1286.     if (len > Cols - MaxNameLen)
  1287.         len = Cols - MaxNameLen;
  1288.     Move(Rp, Xs + MaxNameLen * Rp->TxWidth, Ys + (Rp->TxHeight * i) + Rp->TxBaseline);
  1289.     Text(Rp, rec->comment, len);
  1290.     }
  1291.     if (rec == Highlighted) {
  1292.     SetAPen(Rp, 1);
  1293.     SetBPen(Rp, 0);
  1294.     }
  1295. }
  1296.  
  1297. bigboxhit(y, up)
  1298. {
  1299.     RECORD *hl = Highlighted;
  1300.     short row;
  1301.  
  1302.     Highlighted = NULL;
  1303.     if (hl)
  1304.     redisplayone(hl);
  1305.     row = (y - Ys) / Rp->TxHeight;
  1306.     if (row >= Rows || Rows < 0)
  1307.     return(0);
  1308.     for (hl = DisplayTop; hl && !(hl->flags & R_SELECTED); hl = hl->next);
  1309.     while (hl && row) {
  1310.     if (hl->flags & R_SELECTED)
  1311.         --row;
  1312.     hl = hl->next;
  1313.     }
  1314.     for (; hl && !(hl->flags & R_SELECTED); hl = hl->next);
  1315.     if (Highlighted = hl) {
  1316.     redisplayone(hl);
  1317.     setcomment((hl->comment) ? hl->comment : "");
  1318.     if (up)
  1319.         activate_com();
  1320.     }
  1321. }
  1322.  
  1323. sliderhit()
  1324. {
  1325.     uword pos, fill;
  1326.  
  1327.     getsliderpos(&pos, &fill);
  1328.     NewNumTop = pos * (NumSelected - Rows + 1) / 0xFFFF;
  1329.     redisplay(1);
  1330. }
  1331.  
  1332. /*
  1333.  *  Add a disk volume to the list.  Determine
  1334.  *  the root and add entries beginning at the
  1335.  *  specification.
  1336.  */
  1337.  
  1338. void
  1339. add_volume(str)
  1340. char *str;
  1341. {
  1342.     LOCK *lock;
  1343.     char path[128];
  1344.     int len;
  1345.  
  1346.     Highlighted = NULL;
  1347.     Fib = malloc(sizeof(FIB));
  1348.     if (Fib == NULL)
  1349.     return;
  1350.     resetsort();                /* also cleans up the database  */
  1351.     path[0] = 0;
  1352.     if (lock = Lock(str, ACCESS_READ)) {
  1353.     if (Examine(lock, Fib)) {
  1354.         buildpath(lock, path);
  1355.         len = strlen(path);
  1356.         if (path[len-1] == ':' || path[len-1] == '/') {
  1357.         path[len] = '*';
  1358.         path[len+1] = 0;
  1359.         select_pattern(path, 1);
  1360.         path[len] = 0;
  1361.         }
  1362.         Examine(lock, Fib);
  1363.         if (Fib->fib_DirEntryType < 0) {
  1364.         addentry(path, Fib->fib_Comment, Fib->fib_Size);
  1365.         } else {
  1366.         RECORD *base;
  1367.  
  1368.         /*  find start of killpatterns, if any    */
  1369.         for (base = Rbase; base; base = base->next) {
  1370.             if (strcmp(base->name, KILLNAME) < 0)
  1371.             continue;
  1372.             break;
  1373.         }
  1374.         title("Wait.. Scanning");
  1375.         scandir(lock, path, base);
  1376.         }
  1377.         title("Wait.. Update");
  1378.         rem_selected(NULL,   1);
  1379.     }
  1380.     UnLock(lock);
  1381.     }
  1382.     free(Fib);
  1383.     strcat(path, "*");
  1384.     title("Select path");
  1385.     select_pattern(path, 0);
  1386. }
  1387.  
  1388. buildpath(lock, path)
  1389. LOCK *lock;
  1390. char *path;
  1391. {
  1392.     LOCK *parent;
  1393.     short plen, nlen;
  1394.  
  1395.     plen = strlen(path);
  1396.     nlen = strlen(Fib->fib_FileName) + 1;
  1397.     if (nlen == 1) {    /*  RAM: */
  1398.     strcpy(Fib->fib_FileName, "ram");
  1399.     nlen = 4;
  1400.     }
  1401.     bmov(path, path + nlen, plen + 1);
  1402.     strcpy(path, Fib->fib_FileName);
  1403.     if (Fib->fib_DirEntryType >= 0)
  1404.     path[nlen-1] = '/';
  1405.     if (parent = ParentDir(lock)) {
  1406.     if (Examine(parent, Fib)) {
  1407.         buildpath(parent, path);
  1408.     }
  1409.     UnLock(parent);
  1410.     } else {
  1411.     path[nlen-1] = ':';
  1412.     }
  1413. }
  1414.  
  1415. scandir(lock, path, base)
  1416. LOCK *lock;
  1417. char *path;
  1418. RECORD *base;
  1419. {
  1420.     short restorelen = strlen(path);
  1421.     short len = restorelen;
  1422.     LOCK *olddirlock;
  1423.  
  1424.     if (path[restorelen-1] != ':' && path[restorelen-1] != '/') {
  1425.     strcpy(path + restorelen, "/");
  1426.     ++len;
  1427.     }
  1428.     olddirlock = CurrentDir(lock);
  1429.     if (notkilled(path, base))
  1430.     addentry(path, Fib->fib_Comment, Fib->fib_Size);
  1431.     while (ExNext(lock, Fib)) {
  1432.     strcpy(path+len, Fib->fib_FileName);
  1433.     if (Fib->fib_DirEntryType < 0) {
  1434.         if (notkilled(path, base))
  1435.         addentry(path, Fib->fib_Comment, Fib->fib_Size);
  1436.     } else {
  1437.         LOCK *lock = Lock(Fib->fib_FileName, ACCESS_READ);
  1438.         if (lock) {
  1439.         FIB *oldfib = Fib;
  1440.         if (Fib = malloc(sizeof(FIB))) {
  1441.             Examine(lock, Fib);
  1442.             scandir(lock, path, base);
  1443.             UnLock(lock);
  1444.             free(Fib);
  1445.         }
  1446.         Fib = oldfib;
  1447.         }
  1448.     }
  1449.     }
  1450.     CurrentDir(olddirlock);
  1451.     path[restorelen] = 0;
  1452. }
  1453.  
  1454. notkilled(path,base)
  1455. char *path;
  1456. RECORD *base;
  1457. {
  1458.     while (base && strcmp(base->name, KILLNAME) == 0) {
  1459.     if (base->comment && newwildcmp(base->comment, path))
  1460.         return(0);
  1461.     base = base->next;
  1462.     }
  1463.     return(1);
  1464. }
  1465.  
  1466. load_database(fi)
  1467. FILE *fi;
  1468. {
  1469.     char name[132];
  1470.     char comm[132];
  1471.     char size[32];
  1472.  
  1473.     fgets(name, 128, fi);   /*  # entries per item  */
  1474.     Highlighted = NULL;
  1475.     resetsort();
  1476.     title("Wait... Loading");
  1477.     while (fgets(name, 128, fi) && fgets(comm, 128, fi) && fgets(size, 32, fi)) {
  1478.     name[strlen(name)-1] = 0;   /*  remove newlines */
  1479.     comm[strlen(comm)-1] = 0;
  1480.     addentry(name, comm, atoi(size));
  1481.     }
  1482.     rem_selected(NULL, 1);
  1483.     selectall();
  1484.     redisplay(0);
  1485. }
  1486.  
  1487. save_database(fi)
  1488. FILE *fi;
  1489. {
  1490.     RECORD *rec;
  1491.     char buf[32];
  1492.  
  1493.     cleanup();
  1494.     title("Saving...");
  1495.     fputs("3\n", fi);
  1496.     for (rec = Rbase; rec; rec = rec->next) {
  1497.     fwrite(rec->name, strlen(rec->name), 1, fi);
  1498.     putc('\n', fi);
  1499.     if (rec->comment)
  1500.         fwrite(rec->comment, strlen(rec->comment), 1, fi);
  1501.     putc('\n', fi);
  1502.     sprintf(buf, "%ld\n", rec->bytes);
  1503.     fputs(buf, fi);
  1504.     if (ferror(fi))
  1505.         break;
  1506.     }
  1507. }
  1508.  
  1509. selectall()
  1510. {
  1511.     RECORD *rec;
  1512.     short len;
  1513.  
  1514.     Highlighted = NULL;
  1515.     DisplayTop = NULL;
  1516.     MaxNameLen = 0;
  1517.     for (rec = Rbase; rec; rec = rec->next) {
  1518.     if (rec->flags & R_KILLPAT)
  1519.         continue;
  1520.     len = strlen(rec->name);
  1521.     if (MaxNameLen <= len)
  1522.         MaxNameLen = len + 1;
  1523.     rec->flags |= R_SELECTED;
  1524.     }
  1525.     NumSelected = NumEntries;
  1526. }
  1527.  
  1528. select_pattern(str, noref)
  1529. char *str;
  1530. {
  1531.     register RECORD *rec;
  1532.     register short len;
  1533.     short which = 0;
  1534.  
  1535.     if (*str == '+')    /*  ADD selected patterns   */
  1536.     ++str, which = 1;
  1537.     if (*str == '-')    /*  REMOVE selected patterns*/
  1538.     ++str, which = 2;
  1539.     DisplayTop = NULL;
  1540.     Highlighted= NULL;
  1541.  
  1542.     switch(which) {
  1543.     case 0:
  1544.     NumSelected = 0;
  1545.     MaxNameLen = 0;
  1546.     for (rec = Rbase; rec; rec = rec->next) {
  1547.         rec->flags &= ~R_SELECTED;
  1548.         if (rec->flags & R_KILLPAT)
  1549.         continue;
  1550.         if (newwildcmp(str, rec->name) || (rec->comment && newwildcmp(str, rec->comment))) {
  1551.         if (noref) {
  1552.             rec->flags |= R_UPDATE;
  1553.         } else {
  1554.             rec->flags |= R_SELECTED;
  1555.             ++NumSelected;
  1556.             if ((len = strlen(rec->name)) >= MaxNameLen)
  1557.             MaxNameLen = len + 1;
  1558.         }
  1559.         }
  1560.     }
  1561.     break;
  1562.     case 1:
  1563.     for (rec = Rbase; rec; rec = rec->next) {
  1564.         if ((rec->flags & R_KILLPAT) || (rec->flags & R_SELECTED))
  1565.         continue;
  1566.         if (newwildcmp(str, rec->name) || (rec->comment && newwildcmp(str, rec->comment))) {
  1567.         rec->flags |= R_SELECTED;
  1568.         ++NumSelected;
  1569.         if ((len = strlen(rec->name)) >= MaxNameLen)
  1570.             MaxNameLen = len + 1;
  1571.         }
  1572.     }
  1573.     break;
  1574.     case 2:
  1575.     for (rec = Rbase; rec; rec = rec->next) {
  1576.         if (!(rec->flags & R_SELECTED))
  1577.         continue;
  1578.         if (newwildcmp(str, rec->name) || (rec->comment && newwildcmp(str, rec->comment))) {
  1579.         rec->flags &= ~R_SELECTED;
  1580.         --NumSelected;
  1581.         }
  1582.     }
  1583.     break;
  1584.     }
  1585.     if (!noref)
  1586.     redisplay(0);
  1587. }
  1588.  
  1589. /*
  1590.  *  If onerec != NULL, remove the one record,
  1591.  *  else remove all SELECTED records.
  1592.  */
  1593.  
  1594. rem_selected(onerec, noref)
  1595. RECORD *onerec;
  1596. {
  1597.     register RECORD *rec;
  1598.     register long len, maxlen;
  1599.  
  1600.     Highlighted = NULL;
  1601.     cleanup();
  1602.     if (onerec) {
  1603.     if (onerec->flags & R_SELECTED) {
  1604.         onerec->flags &= ~R_SELECTED;
  1605.         --NumSelected;
  1606.     }
  1607.     onerec->flags |= R_KILLPAT;
  1608.     --NumEntries;
  1609.     } else {
  1610.     maxlen = 0;
  1611.     for (rec = Rbase; rec; rec = rec->next) {
  1612.         if (noref) {
  1613.         if (rec->flags & R_UPDATE) {
  1614.             rec->flags &= ~R_UPDATE;
  1615.             rec->flags |= R_KILLPAT;
  1616.             --NumEntries;
  1617.         }
  1618.         } else {
  1619.         if (rec->flags & R_SELECTED) {
  1620.             rec->flags &= ~R_SELECTED;
  1621.             rec->flags |= R_KILLPAT;
  1622.            --NumEntries;
  1623.         }
  1624.         }
  1625.         if (!(rec->flags & R_KILLPAT) && (len=strlen(rec->name)) > maxlen)
  1626.         maxlen = len;
  1627.     }
  1628.     if (!noref)
  1629.         NumSelected = 0;
  1630.     MaxNameLen = maxlen+1;
  1631.     }
  1632.     if (noref)
  1633.     cleanup();
  1634.     else
  1635.     redisplay(0);
  1636. }
  1637.  
  1638. undo()
  1639. {
  1640.     RECORD *rec;
  1641.  
  1642.     Highlighted = NULL;
  1643.     for (rec = Rbase; rec; rec = rec->next) {
  1644.     if (rec->flags & R_KILLPAT) {
  1645.         rec->flags &= ~R_KILLPAT;
  1646.         rec->flags |= R_SELECTED;
  1647.         ++NumSelected;
  1648.         ++NumEntries;
  1649.         if (strlen(rec->name) >= MaxNameLen)
  1650.         MaxNameLen = strlen(rec->name)+1;
  1651.     }
  1652.     }
  1653.     redisplay(0);
  1654. }
  1655.  
  1656. cleanup()
  1657. {
  1658.     RECORD *rec, *nrec;
  1659.     for (rec = Rbase; rec; rec = nrec) {
  1660.     nrec = rec->next;
  1661.     if (rec->flags & R_KILLPAT) {
  1662.         if (rec == DisplayTop)
  1663.         DisplayTop = nrec;
  1664.         rmrecord(rec);
  1665.     }
  1666.     }
  1667. }
  1668.  
  1669. rmrecord(rec)
  1670. RECORD *rec;
  1671. {
  1672.     if (rec->flags & R_SOFTERR) {
  1673.     puts("panic: soft error");
  1674.     exit(1);
  1675.     }
  1676.     if (rec->prev)
  1677.     rec->prev->next = rec->next;
  1678.     else
  1679.     Rbase = rec->next;
  1680.     if (rec->next)
  1681.     rec->next->prev = rec->prev;
  1682.     rec->flags |= R_SOFTERR;
  1683.     freestr(rec->name);
  1684.     freestr(rec->comment);
  1685.     freerecord(rec);
  1686. }
  1687.  
  1688. /*
  1689.  *  modify the comment field for the highlighted
  1690.  *  item.
  1691.  */
  1692.  
  1693. mod_comment(str)
  1694. char *str;
  1695. {
  1696.     if (Highlighted) {
  1697.     Modified = 1;
  1698.     freestr(Highlighted->comment);
  1699.     if (str[0]) {
  1700.         Highlighted->comment = allocstr(str);
  1701.         if (Highlighted->comment == NULL)
  1702.         title("OUT OF MEMORY!");
  1703.     } else {
  1704.         Highlighted->comment = NULL;
  1705.     }
  1706.     redisplayone(Highlighted);
  1707.     }
  1708. }
  1709.  
  1710.  
  1711. static RECORD *Cache;
  1712.  
  1713. resetsort()
  1714. {
  1715.     cleanup();
  1716.     Cache = Rbase;
  1717. }
  1718.  
  1719. void
  1720. addentry(name, comm, size)
  1721. char *name;
  1722. char *comm;
  1723. long size;
  1724. {
  1725.     RECORD *rec;
  1726.     short n;
  1727.  
  1728.     Modified = 1;
  1729.     rec = allocrecord();
  1730.     if (rec == NULL) {
  1731.     title("OUT OF MEMORY!");
  1732.     return;
  1733.     }
  1734.     rec->name = allocstr(name);
  1735.     if (rec->name == NULL) {
  1736.     rmrecord(rec);
  1737.     title("OUT OF MEMORY!");
  1738.     return;
  1739.     }
  1740.     rec->comment = NULL;
  1741.     if (strlen(comm)) {
  1742.     rec->comment = allocstr(comm);
  1743.     if (rec->comment == NULL) {
  1744.         freestr(rec->name);
  1745.         rmrecord(rec);
  1746.         title("OUT OF MEMORY!");
  1747.         return;
  1748.     }
  1749.     }
  1750.     rec->bytes = size;
  1751.  
  1752.     if (Rbase == NULL) {
  1753.     Rbase = rec;
  1754.     rec->prev = NULL;
  1755.     rec->next = NULL;
  1756.     } else {
  1757.     short n = strcmp(name, Cache->name);
  1758.     if (n == 0 && strcmp(name, KILLNAME) == 0)
  1759.         n = 1;
  1760.     if (n < 0) {                    /*  name < Cache, move backwards */
  1761.         while ((Cache = Cache->prev) && (n=strcmp(name, Cache->name)) < 0);
  1762.     } else
  1763.     if (n > 0) {                    /*  name > Cache, move forwards  */
  1764.         while (Cache->next && (n=strcmp(name, Cache->next->name)) > 0)
  1765.         Cache = Cache->next;
  1766.         if (Cache->next && n == 0)
  1767.         Cache = Cache->next;
  1768.     }
  1769.     if (Cache) {
  1770.         rec->next = Cache->next;    /*  insert after cache */
  1771.         rec->prev = Cache;
  1772.         Cache->next = rec;
  1773.     } else {            /*  or at beginning    */
  1774.         rec->next = Rbase;
  1775.         rec->prev = NULL;
  1776.         Rbase = rec;
  1777.     }
  1778.     if (rec->next)
  1779.         rec->next->prev = rec;
  1780.     if (n == 0) {                   /*  replace if exact   */
  1781.         if (Cache->comment) {
  1782.         char *swap = Cache->comment;
  1783.         Cache->comment = rec->comment;
  1784.         rec->comment = swap;
  1785.         Cache->flags |= R_UPDATE;
  1786.         }
  1787.     }
  1788.     }
  1789.     rec->flags = R_SELECTED;
  1790.     ++NumSelected;
  1791.     ++NumEntries;
  1792.     if (MaxNameLen <= strlen(rec->name))
  1793.     MaxNameLen = strlen(rec->name) + 1;
  1794.     Cache = rec;
  1795. }
  1796.  
  1797. \Rogue\Monster\
  1798. else
  1799.   echo "will not over write files.c"
  1800. fi
  1801. if [ `wc -c files.c | awk '{printf $1}'` -ne 13874 ]
  1802. then
  1803. echo `wc -c files.c | awk '{print "Got " $1 ", Expected " 13874}'`
  1804. fi
  1805. if `test ! -s files.h`
  1806. then
  1807. echo "writing files.h"
  1808. cat > files.h << '\Rogue\Monster\'
  1809.  
  1810. /*
  1811.  *  FILES.H
  1812.  *
  1813.  */
  1814.  
  1815. #include <stdio.h>
  1816. #include <local/typedefs.h>
  1817.  
  1818. #define GAD_INFO    1
  1819. #define GAD_DEL     2
  1820. #define GAD_UNDO    3
  1821. #define GAD_ALL     4
  1822.  
  1823. #define GAD_VOLUME  8
  1824. #define GAD_PATTERN 9
  1825. #define GAD_COMMENT 10
  1826. #define GAD_SLIDER  11
  1827. #define GAD_BIGBOX  12
  1828.  
  1829. #define MEN_SAVE    1
  1830. #define MEN_SAVEAS  2
  1831. #define MEN_LOAD    3
  1832. #define MEN_LOADEF  4
  1833. #define MEN_QUIT    5
  1834. #define MEN_KILLPAT 6
  1835.  
  1836. #define title(str)  SetWindowTitles(Win,(str),NULL)
  1837. #define KILLNAME    "@@KILLPAT"
  1838.  
  1839. #define RECORD    struct _RECORD
  1840.  
  1841. /*
  1842.  *  Each record is stored in the following structure.
  1843.  */
  1844.  
  1845. #define R_SELECTED  0x01    /*    A selected item                 */
  1846. #define R_KILLPAT   0x02    /*    deleted item (undoable)                     */
  1847. #define R_UPDATE    0x04    /*    flag delete (used for updating a volume)    */
  1848. #define R_SOFTERR   0x08    /*    software error if ever encountered!        */
  1849.  
  1850. RECORD {
  1851.     RECORD  *next;    /*  record list, doubly linked        */
  1852.     RECORD  *prev;
  1853.     char    *comment;    /*  comment         */
  1854.     char    *name;    /*  entire file name */
  1855.     long    bytes;    /*  file size         */
  1856.     short   flags;
  1857. };
  1858.  
  1859. extern WIN *OpenWindow();
  1860. extern void *malloc();
  1861. extern void *GetMsg();
  1862. extern void *AllocMem();
  1863.  
  1864. extern RECORD *allocrecord();
  1865. extern char   *allocstr();
  1866.  
  1867. extern RECORD *Rbase;
  1868. extern RECORD *Highlighted;
  1869. extern WIN    *Win;
  1870. extern RP     *Rp;
  1871. extern long   NumEntries;
  1872. extern short  Modified;
  1873.  
  1874.  
  1875. \Rogue\Monster\
  1876. else
  1877.   echo "will not over write files.h"
  1878. fi
  1879. if [ `wc -c files.h | awk '{printf $1}'` -ne 1405 ]
  1880. then
  1881. echo `wc -c files.h | awk '{print "Got " $1 ", Expected " 1405}'`
  1882. fi
  1883. if `test ! -s gadget.c`
  1884. then
  1885. echo "writing gadget.c"
  1886. cat > gadget.c << '\Rogue\Monster\'
  1887.  
  1888. /*
  1889.  *  GADGET.C
  1890.  *
  1891.  *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
  1892.  *
  1893.  */
  1894.  
  1895. #include "files.h"
  1896.  
  1897. #define NI 0
  1898.  
  1899. static BORDER  Bdr[10];
  1900.  
  1901. static ITEXT   BText[] = {
  1902.     { 3,0,JAM2,1,0,NULL,(ubyte *)"info"},
  1903.     { 3,0,JAM2,1,0,NULL,(ubyte *)"del" },
  1904.     { 3,0,JAM2,1,0,NULL,(ubyte *)"undo"},
  1905.     { 3,0,JAM2,1,0,NULL,(ubyte *)"all" }
  1906. };
  1907.  
  1908. static ITEXT   SText[] = {
  1909.     { 3,0,JAM2,NI,-2,NULL,(ubyte *)"Volume:  " },
  1910.     { 3,0,JAM2,NI,-2,NULL,(ubyte *)"Pattern: " },
  1911.     { 3,0,JAM2,NI,-2,NULL,(ubyte *)"Comment: " }
  1912. };
  1913.  
  1914. ubyte Buf1_vol[128]; ubyte Buf2_vol[128];
  1915. ubyte Buf1_pat[128]; ubyte Buf2_pat[128];
  1916. ubyte Buf1_com[128]; ubyte Buf2_com[128];
  1917.  
  1918. STRINGINFO  Si_vol = { Buf1_vol,Buf2_vol,0,sizeof(Buf1_vol),0,0,0,0,0,0 };
  1919. STRINGINFO  Si_pat = { Buf1_pat,Buf2_pat,0,sizeof(Buf2_pat),0,0,0,0,0,0 };
  1920. STRINGINFO  Si_com = { Buf1_com,Buf2_com,0,sizeof(Buf2_com),0,0,0,0,0,0 };
  1921.  
  1922. GADGET    Gad_vol = { NULL    ,  NI,    0, NI, NI, GADGHCOMP|GRELWIDTH,GADGIMMEDIATE|RELVERIFY,STRGADGET,NI,NULL,&SText[0],NULL,(APTR)&Si_vol };
  1923. GADGET    Gad_pat = { &Gad_vol    ,  NI,    1, NI, NI, GADGHCOMP|GRELWIDTH,GADGIMMEDIATE|RELVERIFY,STRGADGET,NI,NULL,&SText[1],NULL,(APTR)&Si_pat };
  1924. GADGET    Gad_com = { &Gad_pat    ,  NI,    2, NI, NI, GADGHCOMP|GRELWIDTH,GADGIMMEDIATE|RELVERIFY,STRGADGET,NI,NULL,&SText[2],NULL,(APTR)&Si_com };
  1925.  
  1926. GADGET    Gad_info= { &Gad_com    ,  5 ,-15, NI, NI, GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[0] };
  1927. GADGET    Gad_del = { &Gad_info    ,  50,-15, NI, NI, GADGHCOMP|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[1] };
  1928. GADGET    Gad_undo= { &Gad_del    ,-110,-15, NI, NI,GADGHCOMP|GRELRIGHT|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[2] };
  1929. GADGET    Gad_all = { &Gad_undo    , -50,-15, NI, NI, GADGHCOMP|GRELRIGHT|GRELBOTTOM,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,NI,NULL,&BText[3] };
  1930.  
  1931. GADGET    *FirstGadget = &Gad_all;
  1932.  
  1933. GADGET    Gad_box = { NULL    ,  NI, NI, NI, NI, GADGHNONE|GRELWIDTH|GRELHEIGHT,GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE,BOOLGADGET,NULL,NULL,NULL };
  1934.  
  1935. PROPINFO Prop_slid = { AUTOKNOB|FREEVERT, 0, 0, 0x30, 0x30 };
  1936. IMAGE     Imag_slid = { 0,0,2,1,1,NULL,1,0,NULL };
  1937.  
  1938. GADGET     Gad_slid  = { NULL,  -20, 12, 20, -30, GADGHCOMP|GRELHEIGHT|GRELRIGHT,GADGIMMEDIATE|RELVERIFY|RIGHTBORDER|FOLLOWMOUSE,PROPGADGET,(APTR)&Imag_slid,NULL,NULL,0,(APTR)&Prop_slid };
  1939.  
  1940. initslider(nw)
  1941. NW *nw;
  1942. {
  1943.     nw->FirstGadget = &Gad_slid;
  1944. }
  1945.  
  1946. initstructs()
  1947. {
  1948.     register short i;
  1949.     register GADGET *gad;
  1950.  
  1951.     for (i = 0; i < sizeof(Bdr)/sizeof(Bdr[0]); ++i) {
  1952.     register BORDER *b = &Bdr[i];
  1953.     register short    *xy= malloc(5 * 2 * sizeof(short));
  1954.     /*b->LeftEdge = b->TopEdge = -2;*/
  1955.     b->FrontPen = 1;
  1956.     b->DrawMode = JAM2;
  1957.     b->Count = 5;
  1958.     b->XY = xy;
  1959.     bzero(xy, 5 * 2 * sizeof(short));
  1960.     xy[2] = i * Win->RPort->TxWidth + 4;
  1961.     xy[4] = xy[2];
  1962.     xy[5] = Win->RPort->TxHeight + 2;
  1963.     xy[7] = Win->RPort->TxHeight + 2;
  1964.     }
  1965.     for (i = 0; i < sizeof(SText)/sizeof(SText[0]); ++i) {
  1966.     register ITEXT *it = &SText[i];
  1967.     it->LeftEdge = -strlen(it->IText) * Win->RPort->TxWidth + 2;
  1968.     it->TopEdge += 2;
  1969.     }
  1970.     for (i = 0; i < sizeof(BText)/sizeof(BText[0]); ++i) {
  1971.     register ITEXT *it = &BText[i];
  1972.     it->LeftEdge+= 2;
  1973.     it->TopEdge += 2;
  1974.     }
  1975.     for (gad = FirstGadget; gad; gad = gad->NextGadget) {
  1976.     register ubyte *str = gad->GadgetText->IText;
  1977.     gad->Height = Win->RPort->TxHeight + 3;
  1978.     gad->Width  = strlen(str) * Win->RPort->TxWidth + 5;
  1979.     if (gad->GadgetType == STRGADGET) {
  1980.         gad->LeftEdge = Win->BorderLeft + strlen(str) * Win->RPort->TxWidth + 2;
  1981.         gad->Width      = -gad->LeftEdge - Win->BorderRight;
  1982.         gad->TopEdge = gad->TopEdge * (Win->RPort->TxHeight + 2) + Win->BorderTop;
  1983.         gad->GadgetText->LeftEdge = -strlen(str) * Win->RPort->TxWidth;
  1984.     } else {
  1985.         gad->GadgetRender = (APTR)&Bdr[strlen(str)];
  1986.     }
  1987.     }
  1988.     Gad_box.LeftEdge= Win->BorderLeft;
  1989.     Gad_box.TopEdge = Gad_com.TopEdge + Win->RPort->TxHeight + 2;
  1990.     Gad_box.Width   = -Gad_box.LeftEdge - Win->BorderRight;
  1991.     Gad_box.Height  = -Gad_box.TopEdge    + Gad_undo.TopEdge - 2;
  1992. }
  1993.  
  1994. addgadgets()
  1995. {
  1996.     register GADGET *gad, *ngad;
  1997.     int i = 0;
  1998.  
  1999.     initstructs(Win);
  2000.     for (gad = FirstGadget; gad; gad = ngad) {
  2001.     ngad = gad->NextGadget;
  2002.     AddGadget(Win, gad, i);
  2003.     ++i;
  2004.     }
  2005.     AddGadget(Win, &Gad_box, i);
  2006.     RefreshGList(FirstGadget, Win, NULL, -1);
  2007. }
  2008.  
  2009. remgadgets()
  2010. {
  2011.  
  2012. }
  2013.  
  2014. fixgadgets()
  2015. {
  2016.  
  2017. }
  2018.  
  2019. getgadget(im, sel, str)
  2020. IMESS *im;
  2021. short *sel;
  2022. ubyte **str;
  2023. {
  2024.     GADGET *gad = (GADGET *)im->IAddress;
  2025.  
  2026.     *sel = gad->Flags & SELECTED;
  2027.  
  2028.     if (gad == &Gad_info) return(GAD_INFO);
  2029.     if (gad == &Gad_del)  return(GAD_DEL);
  2030.     if (gad == &Gad_undo) return(GAD_UNDO);
  2031.     if (gad == &Gad_all)  return(GAD_ALL);
  2032.     if (gad == &Gad_slid) return(GAD_SLIDER);
  2033.     if (gad == &Gad_box)  return(GAD_BIGBOX);
  2034.  
  2035.     if (gad == &Gad_vol || gad == &Gad_pat || gad == &Gad_com) {
  2036.     *str = ((STRINGINFO *)gad->SpecialInfo)->Buffer;
  2037.     if (gad == &Gad_vol) return(GAD_VOLUME);
  2038.     if (gad == &Gad_pat) return(GAD_PATTERN);
  2039.     if (gad == &Gad_com) return(GAD_COMMENT);
  2040.     }
  2041.     return(0);
  2042. }
  2043.  
  2044. bigboxbounds(xs,xe,ys,ye)
  2045. short *xs,*xe,*ys,*ye;
  2046. {
  2047.     *xs = Gad_box.LeftEdge;
  2048.     *xe = *xs + Gad_box.Width + Win->Width;
  2049.     *ys = Gad_box.TopEdge;
  2050.     *ye = *ys + Gad_box.Height+ Win->Height;
  2051.     if (*xe <= *xs)
  2052.     *xe = *xs + 1;
  2053.     if (*ye <= *ys)
  2054.     *ye = *ys + 1;
  2055. }
  2056.  
  2057. getsliderpos(pot, full)
  2058. short *pot, *full;
  2059. {
  2060.     *pot = Prop_slid.VertPot;
  2061.     *full= Prop_slid.VertBody;
  2062. }
  2063.  
  2064. getboxpos(im)
  2065. IMESS *im;
  2066. {
  2067.     return(im->MouseY - Gad_box.TopEdge);
  2068. }
  2069.  
  2070. setslider(pos, fatness)
  2071. {
  2072.     NewModifyProp(&Gad_slid, Win, NULL, AUTOKNOB|FREEVERT,0,pos,0,fatness,1);
  2073. }
  2074.  
  2075. setcomment(str)
  2076. char *str;
  2077. {
  2078.     strcpy(Buf1_com, str);
  2079.     RefreshGList(&Gad_com, Win, NULL, 1);
  2080. }
  2081.  
  2082. activate_vol()
  2083. {
  2084.     ActivateGadget(&Gad_vol, Win, NULL);
  2085. }
  2086.  
  2087. activate_pat()
  2088. {
  2089.     ActivateGadget(&Gad_pat, Win, NULL);
  2090. }
  2091.  
  2092. activate_com()
  2093. {
  2094.     ActivateGadget(&Gad_com, Win, NULL);
  2095. }
  2096.  
  2097. \Rogue\Monster\
  2098. else
  2099.   echo "will not over write gadget.c"
  2100. fi
  2101. if [ `wc -c gadget.c | awk '{printf $1}'` -ne 5780 ]
  2102. then
  2103. echo `wc -c gadget.c | awk '{print "Got " $1 ", Expected " 5780}'`
  2104. fi
  2105. if `test ! -s main.c`
  2106. then
  2107. echo "writing main.c"
  2108. cat > main.c << '\Rogue\Monster\'
  2109.  
  2110. /*
  2111.  *  MAIN.C
  2112.  *
  2113.  *  FILES
  2114.  *
  2115.  *  A file catalog program by Matthew Dillon.
  2116.  *
  2117.  *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
  2118.  *
  2119.  */
  2120.  
  2121. #include "files.h"
  2122. #include <local/xmisc.h>
  2123.  
  2124. short Deemu[] = {
  2125.     'ST','RT', 0, 0,
  2126.     'NW','  ', 0, 8, -16, -8, 320, 100,
  2127.     'TE','XT', 0,42, 'De','fa','ul','t\0','s:','ca','ta','lo','g.','db',0,0,0,0,0,0,0,0,0,0,0,
  2128.     'EN','D ', 0, 0
  2129. };
  2130.  
  2131. #define NWOFF    8
  2132. #define DEFFILE 16
  2133.  
  2134. NW Nw = {
  2135.     0, 0, 0, 0, -1, -1,
  2136.     NEWSIZE|MOUSEBUTTONS|MOUSEMOVE|GADGETDOWN|GADGETUP|MENUPICK|CLOSEWINDOW,
  2137.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|ACTIVATE,
  2138.     NULL, NULL, (ubyte *)"V1.2 by Matthew Dillon, Catalog Utility.", NULL,
  2139.     NULL, 182, 66, -1, -1, WBENCHSCREEN
  2140. };
  2141.  
  2142. WIN *Win;
  2143. RP  *Rp;
  2144.  
  2145. char FileName[128];
  2146.  
  2147. main()
  2148. {
  2149.     char resized = 0;
  2150.     char notdone = 1;
  2151.     char movebox = 0;
  2152.     char moveslider = 0;
  2153.     char addactive = 0;
  2154.     char noload = 1;
  2155.     char dontquit = 0;
  2156.  
  2157.     char mmove = 0;
  2158.     short mmy;
  2159.  
  2160.     IMESS *im;
  2161.     SCR   Scr;
  2162.  
  2163.     openlibs(INTUITION_LIB|GRAPHICS_LIB);
  2164.  
  2165.     GetScreenData(&Scr, sizeof(Scr), WBENCHSCREEN, NULL);
  2166.  
  2167.     initslider(&Nw);
  2168.  
  2169.     Nw.LeftEdge = Deemu[NWOFF+0];
  2170.     Nw.TopEdge    = Deemu[NWOFF+1];
  2171.     Nw.Width    = Deemu[NWOFF+2];
  2172.     Nw.Height    = Deemu[NWOFF+3];
  2173.     if (Nw.Width <= 0)
  2174.     Nw.Width += Scr.Width;
  2175.     if (Nw.Height <= 0)
  2176.     Nw.Height += Scr.Height;
  2177.     if (Nw.LeftEdge < 0)
  2178.     Nw.LeftEdge += Scr.Width - Nw.Width;
  2179.     if (Nw.TopEdge < 0)
  2180.     Nw.TopEdge  += Scr.Height- Nw.Height;
  2181.     if (Nw.LeftEdge < 0 || Nw.TopEdge < 0 || Nw.LeftEdge + Nw.Width > Scr.Width || Nw.TopEdge + Nw.Height > Scr.Height) {
  2182.     Nw.LeftEdge = Nw.TopEdge = 0;
  2183.     Nw.Width = 320;
  2184.     Nw.Height= 100;
  2185.     }
  2186.     {
  2187.     register char *ptr = (char *)(Deemu + DEFFILE);
  2188.     strcpy(FileName, ptr + strlen(ptr) + 1);
  2189.     }
  2190.  
  2191.     Win = OpenWindow(&Nw);
  2192.     failfalse(Win, "Unable to open window");
  2193.     Rp = Win->RPort;
  2194.  
  2195.     addmenus();
  2196.     addgadgets();
  2197. again:
  2198.     for (; notdone || dontquit;) {
  2199.     if (dontquit)
  2200.         notdone = 1;
  2201.     dontquit = 0;
  2202.     WaitPort(Win->UserPort);
  2203.     while (im = GetMsg(Win->UserPort)) {
  2204.         switch(im->Class) {
  2205.         case NEWSIZE:
  2206.         resized = 1;
  2207.         break;
  2208.         case MOUSEBUTTONS:
  2209.         break;
  2210.         case MOUSEMOVE:
  2211.         mmove = 1;
  2212.         mmy = im->MouseY;
  2213.         break;
  2214.         case GADGETDOWN:
  2215.         {
  2216.             char *str = NULL;
  2217.             short sel;
  2218.             switch(getgadget(im, &sel, &str)) {
  2219.             case GAD_SLIDER:
  2220.             moveslider = 1;
  2221.             movebox = 0;
  2222.             sliderhit();
  2223.             break;
  2224.             case GAD_BIGBOX:
  2225.             moveslider = 0;
  2226.             movebox = 1;
  2227.             bigboxhit(im->MouseY, 0);
  2228.             break;
  2229.             }
  2230.         }
  2231.         break;
  2232.         case GADGETUP:
  2233.         {
  2234.             char *str = NULL;
  2235.             short sel;
  2236.             switch(getgadget(im, &sel, &str)) {
  2237.             case GAD_INFO:
  2238.             {
  2239.                 long fh = Open("raw:10/24/600/150/INFO", 1006);
  2240.                 if (fh) {
  2241.                 char buf[8];
  2242.                 fhprintf(fh, "\n\r\n\rVersion 1.1  Written by Matthew Dillon\n\r");
  2243.                 fhprintf(fh, "(c)Copyright 1987 Matthew Dillon, All Rights Reserved.\n\n\r");
  2244.                 fhprintf(fh, "    dillon@ucbvax.berkeley.edu     (ARPANET)\n\r");
  2245.                 fhprintf(fh, "    ...!ihnp4!ucbvax!dillon        (USENET)\n\r");
  2246.                 fhprintf(fh, "Matthew Dillon, 891 Regal Rd. Berkeley, Ca. 94708\n\n\r");
  2247.                 fhprintf(fh, "This software is freely redistributable only.  This\n\r");
  2248.                 fhprintf(fh, "software is NOT shareware\n\n\r");
  2249.                 fhprintf(fh, "Thanks to Peter Da Silva for providing the filerequestor\n\r");
  2250.                 fhprintf(fh, "\n\n    Any key to continue\n\r");
  2251.                 Read(fh, buf, 1);
  2252.                 Close(fh);
  2253.                 }
  2254.             }
  2255.             break;
  2256.             case GAD_DEL:
  2257.             rem_selected(Highlighted, 0);
  2258.             break;
  2259.             case GAD_UNDO:
  2260.             undo();
  2261.             break;
  2262.             case GAD_ALL:
  2263.             selectall();
  2264.             redisplay(0);
  2265.             break;
  2266.             case GAD_VOLUME:
  2267.             if (str[0])
  2268.                 add_volume(str);
  2269.             activate_vol();
  2270.             break;
  2271.             case GAD_PATTERN:
  2272.             if (str[0]) {
  2273.                 title("Wait");
  2274.                 select_pattern(str, 0);
  2275.             }
  2276.             activate_pat();
  2277.             break;
  2278.             case GAD_COMMENT:
  2279.             mod_comment(str);
  2280.             break;
  2281.             case GAD_SLIDER:
  2282.             moveslider = 0;
  2283.             sliderhit();
  2284.             break;
  2285.             case GAD_BIGBOX:
  2286.             movebox = 0;
  2287.             bigboxhit(im->MouseY, 1);
  2288.             break;
  2289.             }
  2290.         }
  2291.         break;
  2292.         case MENUPICK:
  2293.         switch(getmenu(im)) {
  2294.         case MEN_SAVE:
  2295.             {
  2296.             FILE *fi;
  2297.             if (noload && NumEntries == 0) {
  2298.                 title("Did I just save you from making a mistake?");
  2299.                 break;
  2300.             }
  2301.             fi = fopen(FileName, "w");
  2302.             if (fi) {
  2303.                 save_database(fi);
  2304.                 if (ferror(fi)) {
  2305.                 title("File Error");
  2306.                 dontquit = 1;
  2307.                 } else {
  2308.                 title("Saved ok");
  2309.                 Modified = 0;
  2310.                 }
  2311.                 fclose(fi);
  2312.             } else {
  2313.                 title("Unable to open file for write");
  2314.             }
  2315.             }
  2316.             break;
  2317.         case MEN_SAVEAS:
  2318.             {
  2319.             FILE *fi;
  2320.             if (stdfile("SAVE DATABASE", FileName, "", FileName)) {
  2321.                 noload = 0;
  2322.                 if (fi = fopen(FileName, "w")) {
  2323.                 save_database(fi);
  2324.                 if (ferror(fi)) {
  2325.                     title("File Error");
  2326.                     dontquit = 1;
  2327.                 } else {
  2328.                     title("Saved ok");
  2329.                     Modified = 0;
  2330.                 }
  2331.                 fclose(fi);
  2332.                 } else {
  2333.                 title("Unable to open file for write");
  2334.                 }
  2335.             }
  2336.             }
  2337.             break;
  2338.         case MEN_LOADEF:
  2339.             {
  2340.             FILE *fi = fopen(FileName, "r");
  2341.             long entries = NumEntries;
  2342.             if (fi) {
  2343.                 noload = 0;
  2344.                 load_database(fi);
  2345.                 if (!entries)
  2346.                 Modified = 0;
  2347.                 fclose(fi);
  2348.             } else {
  2349.                 title("Unable to open file for read");
  2350.             }
  2351.             }
  2352.             break;
  2353.         case MEN_LOAD:
  2354.             {
  2355.             FILE *fi;
  2356.             long entries = NumEntries;
  2357.             if (stdfile("LOAD DATABASE", FileName, "", FileName)) {
  2358.                 noload = 0;
  2359.                 if (fi = fopen(FileName, "r")) {
  2360.                 load_database(fi);
  2361.                 if (!entries)
  2362.                     Modified = 0;
  2363.                 fclose(fi);
  2364.                 } else {
  2365.                 title("Unable to open file for read");
  2366.                 }
  2367.             }
  2368.             }
  2369.             break;
  2370.         case MEN_QUIT:
  2371.             notdone = 0;
  2372.             break;
  2373.         case MEN_KILLPAT:
  2374.             resetsort();
  2375.             addentry(KILLNAME, "", 0);
  2376.             select_pattern(KILLNAME, 0);
  2377.             break;
  2378.         }
  2379.         break;
  2380.         case CLOSEWINDOW:
  2381.         notdone = 0;
  2382.         break;
  2383.         }
  2384.         ReplyMsg(im);
  2385.         if (resized) {
  2386.         fixgadgets();
  2387.         redisplay(0);
  2388.         }
  2389.         resized = 0;
  2390.     }
  2391.     if (mmove) {
  2392.         if (moveslider)
  2393.         sliderhit();
  2394.         if (movebox)
  2395.         bigboxhit(mmy, 0);
  2396.         mmove = 0;
  2397.     }
  2398.     }
  2399.     if (Modified) {
  2400.     title("MODIFICATIONS MADE!  HIT CLOSE-BOX AGAIN TO VERIFY");
  2401.     Modified = 0;
  2402.     notdone = 1;
  2403.     goto again;
  2404.     }
  2405.     failfalse(NULL, NULL);
  2406. }
  2407.  
  2408. failfalse(val, str)
  2409. long val;
  2410. char *str;
  2411. {
  2412.     if (val == NULL) {
  2413.     if (str)
  2414.         puts(str);
  2415.     if (Win) {
  2416.         remmenus();
  2417.         remgadgets();
  2418.         CloseWindow(Win);
  2419.         Win = NULL;
  2420.     }
  2421.     closelibs(-1);
  2422.     exit((str)? 1 : 0);
  2423.     }
  2424. }
  2425.  
  2426. failtrue(val, str)
  2427. long val;
  2428. char *str;
  2429. {
  2430.     if (val)
  2431.     failfalse(NULL, str);
  2432. }
  2433.  
  2434. \Rogue\Monster\
  2435. else
  2436.   echo "will not over write main.c"
  2437. fi
  2438. if [ `wc -c main.c | awk '{printf $1}'` -ne 6575 ]
  2439. then
  2440. echo `wc -c main.c | awk '{print "Got " $1 ", Expected " 6575}'`
  2441. fi
  2442. if `test ! -s memory.c`
  2443. then
  2444. echo "writing memory.c"
  2445. cat > memory.c << '\Rogue\Monster\'
  2446.  
  2447. /*
  2448.  *  MEMORY.C
  2449.  *
  2450.  *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
  2451.  *
  2452.  */
  2453.  
  2454. #include "files.h"
  2455.  
  2456. #define BLKSIZE     256     /*    # of records to allocate at once    */
  2457. #define STRBLKSIZE  4096
  2458. #define MAXSTRLEN   64        /*    maximum string len for cached strings    */
  2459.  
  2460. static RECORD *Freelist;
  2461. static RECORD *Blk;
  2462. static short  Bi;
  2463. static char   *Strs[MAXSTRLEN];
  2464. static char   *Sbuf;
  2465. static short  Si;
  2466.  
  2467. RECORD *
  2468. allocrecord()
  2469. {
  2470.     register RECORD *rec;
  2471.     if (rec = Freelist) {
  2472.     Freelist = Freelist->next;
  2473.     return(rec);
  2474.     }
  2475.     if (!Bi) {
  2476.     Blk = (RECORD *)malloc(sizeof(RECORD) * BLKSIZE);
  2477.     if (!Blk)
  2478.         return(NULL);
  2479.     Bi = 256;
  2480.     }
  2481.     --Bi;
  2482.     return(Blk++);
  2483. }
  2484.  
  2485. void
  2486. freerecord(rec)
  2487. RECORD *rec;
  2488. {
  2489.     rec->next = Freelist;
  2490.     Freelist = rec;
  2491. }
  2492.  
  2493. char *
  2494. allocstr(str)
  2495. char *str;
  2496. {
  2497.     register short bytes = strlen(str) + 1;
  2498.     register char *ptr;
  2499.  
  2500.     if (bytes >= 4 && bytes < MAXSTRLEN) {
  2501.     if (Strs[bytes]) {
  2502.         ptr = Strs[bytes];
  2503.         Strs[bytes] = *(char **)ptr;
  2504.     } else {
  2505.         bytes = (bytes + 1) & ~1;
  2506.         if (Si < bytes) {
  2507.         Sbuf = malloc(STRBLKSIZE);
  2508.         if (!Sbuf)
  2509.             return(NULL);
  2510.         Si = STRBLKSIZE;
  2511.         }
  2512.         ptr = Sbuf;
  2513.         Sbuf += bytes;
  2514.         Si -= bytes;
  2515.     }
  2516.     } else {
  2517.     ptr = malloc(bytes);
  2518.     if (!ptr)
  2519.         return(NULL);
  2520.     }
  2521.     strcpy(ptr, str);
  2522.     return(ptr);
  2523. }
  2524.  
  2525. void
  2526. freestr(ptr)
  2527. char *ptr;
  2528. {
  2529.     register short len;
  2530.  
  2531.     if (ptr) {
  2532.     len = strlen(ptr) + 1;
  2533.     if (len >= 4 && len < MAXSTRLEN) {
  2534.         *(char **)ptr = Strs[len];
  2535.         Strs[len] = ptr;
  2536.     } else {
  2537.         free(ptr);
  2538.     }
  2539.     }
  2540. }
  2541.  
  2542. \Rogue\Monster\
  2543. else
  2544.   echo "will not over write memory.c"
  2545. fi
  2546. if [ `wc -c memory.c | awk '{printf $1}'` -ne 1531 ]
  2547. then
  2548. echo `wc -c memory.c | awk '{print "Got " $1 ", Expected " 1531}'`
  2549. fi
  2550. if `test ! -s menu.c`
  2551. then
  2552. echo "writing menu.c"
  2553. cat > menu.c << '\Rogue\Monster\'
  2554.  
  2555. /*
  2556.  *  MENU.C
  2557.  *
  2558.  *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
  2559.  *
  2560.  */
  2561.  
  2562. #include "files.h"
  2563.  
  2564. #define NI  0        /*    means 'not initialized' */
  2565.  
  2566. static ITEXT IText[] = {
  2567.     { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Save"        },
  2568.     { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"SaveAs"      },
  2569.     { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Load"        },
  2570.     { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"LoadDefault" },
  2571.     { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Quit"        },
  2572.     { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"AddKillPat"  },
  2573. };
  2574.  
  2575. static ITEM Item[] = {
  2576.     { &Item[1], 0, NI, NI, NI, 0, 0, (APTR)&IText[0], NULL },
  2577.     { &Item[2], 0, NI, NI, NI, 0, 0, (APTR)&IText[1], NULL },
  2578.     { &Item[3], 0, NI, NI, NI, 0, 0, (APTR)&IText[2], NULL },
  2579.     { &Item[4], 0, NI, NI, NI, 0, 0, (APTR)&IText[3], NULL },
  2580.     { NULL    , 0, NI, NI, NI, 0, 0, (APTR)&IText[4], NULL },
  2581.     { NULL    , 0, NI, NI, NI, 0, 0, (APTR)&IText[5], NULL },
  2582. };
  2583.  
  2584. static MENU Menu[] = {
  2585.     { &Menu[1], NI, 0, NI, NI, NI, "Project" , NI },
  2586.     { NULL    , NI, 0, NI, NI, NI, "Control", NI  }
  2587. };
  2588.  
  2589.  
  2590. addmenus()
  2591. {
  2592.     MENU *menu;
  2593.     ITEM *item, *nit;
  2594.     short left = 5;
  2595.     short height;
  2596.     short width;
  2597.  
  2598.     for (menu = Menu, item = Item; menu; menu = menu->NextMenu) {
  2599.     height = 0;
  2600.     width  = strlen(menu->MenuName);
  2601.     menu->FirstItem = item;
  2602.     for (item = menu->FirstItem; item; item = item->NextItem) {
  2603.         if (width < strlen(((ITEXT *)item->ItemFill)->IText))
  2604.         width = strlen(((ITEXT *)item->ItemFill)->IText);
  2605.     }
  2606.     width *= Win->RPort->TxWidth;
  2607.     for (item = menu->FirstItem; item; nit = item, item = item->NextItem) {
  2608.         item->Width   = width;
  2609.         item->Height  = Win->RPort->TxHeight + 2;
  2610.         item->TopEdge = height;
  2611.         item->Flags  |= ITEMTEXT|ITEMENABLED|HIGHCOMP;
  2612.         height += item->Height;
  2613.     }
  2614.     menu->LeftEdge = left;
  2615.     menu->Width    = width;
  2616.     menu->Height   = height;
  2617.     menu->Flags    = MENUENABLED;
  2618.     item = nit + 1;
  2619.     left += width + 4;
  2620.     }
  2621.     SetMenuStrip(Win, Menu);
  2622. }
  2623.  
  2624. remmenus()
  2625. {
  2626.     ClearMenuStrip(Win);
  2627. }
  2628.  
  2629. getmenu(im)
  2630. IMESS *im;
  2631. {
  2632.     register short mn = MENUNUM(im->Code);
  2633.     register short in = ITEMNUM(im->Code);
  2634.  
  2635.     switch(mn) {
  2636.     case 0:
  2637.     switch(in) {
  2638.     case 0:
  2639.         return(MEN_SAVE);
  2640.     case 1:
  2641.         return(MEN_SAVEAS);
  2642.     case 2:
  2643.         return(MEN_LOAD);
  2644.     case 3:
  2645.         return(MEN_LOADEF);
  2646.     case 4:
  2647.         return(MEN_QUIT);
  2648.     }
  2649.     break;
  2650.     case 1:
  2651.     switch(in) {
  2652.     case 0:
  2653.         return(MEN_KILLPAT);
  2654.     }
  2655.     break;
  2656.     }
  2657.     return(0);
  2658. }
  2659.  
  2660. \Rogue\Monster\
  2661. else
  2662.   echo "will not over write menu.c"
  2663. fi
  2664. if [ `wc -c menu.c | awk '{printf $1}'` -ne 2411 ]
  2665. then
  2666. echo `wc -c menu.c | awk '{print "Got " $1 ", Expected " 2411}'`
  2667. fi
  2668. if `test ! -s newwildcmp.c`
  2669. then
  2670. echo "writing newwildcmp.c"
  2671. cat > newwildcmp.c << '\Rogue\Monster\'
  2672.  
  2673. /*
  2674.  *  NEWWILDCMP.C
  2675.  *
  2676.  *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
  2677.  *
  2678.  *  Compare a wild card name with a normal name
  2679.  *
  2680.  *  This function replaces wildcmp() in SUP32.LIB (as not everybody will
  2681.  *  have the latest SUP32.LIB).  The only difference is that this call
  2682.  *  is case insensitive.  Later releases of SUP32.LIB will fix the
  2683.  *  case-sensitive bug.
  2684.  */
  2685.  
  2686. #define MAXB   8
  2687.  
  2688. newwildcmp(wild, name)
  2689. char *wild, *name;
  2690. {
  2691.     register char *w = wild;
  2692.     register char *n = name;
  2693.     char *back[MAXB][2];
  2694.     register short bi = 0;
  2695.     register char c1, c2;
  2696.  
  2697.     while (*n || *w) {
  2698.     switch (*w) {
  2699.     case '*':
  2700.         if (bi == MAXB) {
  2701.         puts ("Too many levels of '*'");
  2702.         return (0);
  2703.         }
  2704.         back[bi][0] = w;
  2705.         back[bi][1] = n;
  2706.         ++bi;
  2707.         ++w;
  2708.         continue;
  2709. goback:
  2710.         --bi;
  2711.         while (bi >= 0 && *back[bi][1] == '\0')
  2712.         --bi;
  2713.         if (bi < 0)
  2714.         return (0);
  2715.         w = back[bi][0] + 1;
  2716.         n = ++back[bi][1];
  2717.         ++bi;
  2718.         continue;
  2719.     case '?':
  2720.         if (!*n) {
  2721.         if (bi)
  2722.             goto goback;
  2723.         return (0);
  2724.         }
  2725.         break;
  2726.     default:
  2727.         c1 = *n;
  2728.         c2 = *w;
  2729.         if (c1 >= 'A' && c1 <= 'Z')     /*  to lower case */
  2730.         c1 |= 0x20;
  2731.         if (c2 >= 'A' && c2 <= 'Z')
  2732.         c2 |= 0x20;
  2733.         if (c1 != c2) {
  2734.         if (bi)
  2735.             goto goback;
  2736.         return (0);
  2737.         }
  2738.         break;
  2739.     }
  2740.     if (*n)  ++n;
  2741.     if (*w)  ++w;
  2742.     }
  2743.     return (1);
  2744. }
  2745.  
  2746.  
  2747. \Rogue\Monster\
  2748. else
  2749.   echo "will not over write newwildcmp.c"
  2750. fi
  2751. if [ `wc -c newwildcmp.c | awk '{printf $1}'` -ne 1351 ]
  2752. then
  2753. echo `wc -c newwildcmp.c | awk '{print "Got " $1 ", Expected " 1351}'`
  2754. fi
  2755. echo "Finished archive 1 of 1"
  2756. # if you want to concatenate archives, remove anything after this line
  2757. exit
  2758. -- 
  2759. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2760. Have five nice days.
  2761.